ChatGPT解决这个技术问题 Extra ChatGPT

Automatically creating directories with file output [duplicate]

This question already has answers here: mkdir -p functionality in Python [duplicate] (12 answers) Closed 4 months ago.

Say I want to make a file:

filename = "/foo/bar/baz.txt"

with open(filename, "w") as f:
    f.write("FOOBAR")

This gives an IOError, since /foo/bar does not exist.

What is the most pythonic way to generate those directories automatically? Is it necessary for me explicitly call os.path.exists and os.mkdir on every single one (i.e., /foo, then /foo/bar)?


P
P i

COMMUNITY EDIT: As question is closed, @David258's answer is written as a comment.

from pathlib import Path
output_file = Path("/foo/bar/baz.txt")
output_file.parent.mkdir(exist_ok=True, parents=True)
output_file.write_text("FOOBAR")

I leave it to the author of this answer to fold this in or remove it as they see fit.

Original answer starts here:

In Python 3.2+, you can elegantly do the following:


import os

filename = "/foo/bar/baz.txt"
os.makedirs(os.path.dirname(filename), exist_ok=True)
with open(filename, "w") as f:
    f.write("FOOBAR")

In older python, there is a less elegant way:

The os.makedirs function does this. Try the following:

import os
import errno

filename = "/foo/bar/baz.txt"
if not os.path.exists(os.path.dirname(filename)):
    try:
        os.makedirs(os.path.dirname(filename))
    except OSError as exc: # Guard against race condition
        if exc.errno != errno.EEXIST:
            raise

with open(filename, "w") as f:
    f.write("FOOBAR")

The reason to add the try-except block is to handle the case when the directory was created between the os.path.exists and the os.makedirs calls, so that to protect us from race conditions.


Just had to look past os.mkdir and read the documentation on one more function :)
There is a slightly different approach here: stackoverflow.com/a/14364249/1317713 Thoughts?
Is the inital if not os.path.exists needed since the os.makedirs uses EAFP?
PermissionError: [Errno 13] Permission denied: '/foo'
with Pathlib: from pathlib import Path; output_file = Path("/foo/bar/baz.txt"); output_file.parent.mkdir(exist_ok=True, parents=True); output_file.write_text("FOOBAR")