44

How do I using with open() as f: ... to write the file in a directory that doesn't exist.

For example:

with open('/Users/bill/output/output-text.txt', 'w') as file_to_write:
    file_to_write.write("{}\n".format(result))

Let's say the /Users/bill/output/ directory doesn't exist. If the directory doesn't exist just create the directory and write the file there.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Billz
  • 7,879
  • 7
  • 33
  • 35
  • I've been using [this snippet](http://code.activestate.com/recipes/82465-a-friendly-mkdir/) for years and years. – dabhaid May 21 '14 at 21:37

5 Answers5

69

You need to first create the directory.

The mkdir -p implementation from this answer will do just what you want. mkdir -p will create any parent directories as required, and silently do nothing if it already exists.

Here I've implemented a safe_open_w() method which calls mkdir_p on the directory part of the path, before opening the file for writing:

import os, os.path
import errno

# Taken from https://stackoverflow.com/a/600612/119527
def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc: # Python >2.5
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else: raise

def safe_open_w(path):
    ''' Open "path" for writing, creating any parent directories as needed.
    '''
    mkdir_p(os.path.dirname(path))
    return open(path, 'w')

with safe_open_w('/Users/bill/output/output-text.txt') as f:
    f.write(...)

Updated for Python 3:

import os, os.path

def safe_open_w(path):
    ''' Open "path" for writing, creating any parent directories as needed.
    '''
    os.makedirs(os.path.dirname(path), exist_ok=True)
    return open(path, 'w')

with safe_open_w('/Users/bill/output/output-text.txt') as f:
    f.write(...)
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
44

Using pathlib.Path (in Python 3.5 and up, to support the exist_ok parameter):

from pathlib import Path

p = Path('Users') / 'bill' / 'output'
p.mkdir(exist_ok=True)
with (p / 'output-text.txt').open('w') as opened_file:
    opened_file.write(...)
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Yakir Tsuberi
  • 1,373
  • 1
  • 12
  • 16
  • 11
    This should be the accepted answer in 2020. There is no need to mess with custom functions and the os module anymore. – Jeff Wright Aug 09 '20 at 15:46
  • 1
    Note you may want to specify `parents=True` to get the expected behavior of creating all directories that don't exist for the file. – Major Major Nov 09 '22 at 03:31
16

Make liberal use of the os module:

import os

if not os.path.isdir('/Users/bill/output'):
    os.mkdir('/Users/bill/output')

with open('/Users/bill/output/output-text.txt', 'w') as file_to_write:
    file_to_write.write("{}\n".format(result))
huu
  • 7,032
  • 2
  • 34
  • 49
13

The answer given by Yakir Tsuberi is great but I would like to add that you need the parameter parents=True for nested folders as explained here. Thus, the code would look as follows:

from pathlib import Path

p = Path('Users/bill/output')
p.mkdir(parents=True, exist_ok=True)
with (p / 'output-text.txt').open('w') as opened_file:
    opened_file.write(...)
Neuron
  • 5,141
  • 5
  • 38
  • 59
Hagbard
  • 3,430
  • 5
  • 28
  • 64
2

You can just create the path you want to create the file using os.makedirs:

import os
import errno

def make_dir(path):
    try:
        os.makedirs(path, exist_ok=True)  # Python>3.2
    except TypeError:
        try:
            os.makedirs(path)
        except OSError as exc: # Python >2.5
            if exc.errno == errno.EEXIST and os.path.isdir(path):
                pass
            else: raise

Source: this SO solution

Community
  • 1
  • 1
Alex Gidan
  • 2,619
  • 17
  • 29