1

I'm trying to create the full path all at once if it doesn't already exist, but I'm not sure it's possible. This is my code now:

absolute_path = '/home/{signup_code}/{resource}/process'
missing_file = absolute_path.format(resource='agents', signup_code=signup_code)
with open(missing_file, 'a') as f:
    f.write(listing_kwargs['agent_id'] + "\n")

And this is the error I'm getting:

FileNotFoundError: [Errno 2] No such file or directory: '/home/ith/agents/process'

Or do I have to do something like this:

path = '/home/{signup_code}/{resource}/'
os.makedirs(path, exist_ok=True)

process = os.path.join(path, 'process')

with open(process, 'a') as f:
    f.write(listing_kwargs['agent_id'] + "\n")
Dusty
  • 1,053
  • 2
  • 11
  • 24
  • @StefanoSanfilippo doesn't that question provide a solution to recursively creating directories, while my question asks for a way to create the file in addition to the directories? – Dusty Jun 08 '15 at 19:46
  • Once you have created all the directories in `absolute_path`, you can simply `open(missing_file, 'a')` and it will work. So yes, the real issue here is the one addressed in that question. – Stefano Sanfilippo Jun 08 '15 at 19:51
  • But my question asks to `Create directories and filename all at once` and if you're saying I can't, then the real answer is that the built-in `open()` function doesn't support that and there's no other Python function that supports that either. – Dusty Jun 08 '15 at 20:52

1 Answers1

1

There's no way to do this directly. You're going to need to break it down into two parts. First, create the path using os.makedirs(), and then open the file. The nice thing is that you can wrap this process in a function, so that it's easily repeatable:

import os
from contextlib import contextmanager

@contextmanager
def open_with_create_path(fname, file_mode='r', buffering=-1,
                          encoding=None, errors=None, newline=None,
                          dir_mode=0o777, exist_ok=True):
    os.makedirs(os.path.dirname(fname), mode=dir_mode, exist_ok=exist_ok)
    f = open(fname, mode=file_mode, buffering=buffering, encoding=encoding,
             errors=errors, newline=newline)
    try:
        yield f
    finally:
        f.close()

FNAME = r'C:\temp\foo\bar\baz.txt'
with open_with_create_path(FNAME, 'w') as f:
    print('foo', file=f)
Deacon
  • 3,615
  • 2
  • 31
  • 52