Recursively create directories prior to opening file for writing

折月煮酒 提交于 2021-01-27 06:52:02

问题


I need to write to a file (truncating) and the path it is on itself might not exist). For example, I want to write to /tmp/a/b/c/config, but /tmp/a itself might not exist. Then, open('/tmp/a/b/c/config', 'w') would not work, obviously, since it doesn't make the necessary directories. However, I can work with the following code:

import os

config_value = 'Foo=Bar'  # Temporary placeholder

config_dir = '/tmp/a/b/c'  # Temporary placeholder
config_file_path = os.path.join(config_dir, 'config')

if not os.path.exists(config_dir):
    os.makedirs(config_dir)

with open(config_file_path, 'w') as f:
    f.write(config_value)

Is there a more Pythonic way to do this? Both Python 2.x and Python 3.x would be nice to know (even though I use 2.x in my code, due to dependency reasons).


回答1:


If you're repeating this pattern in multiple places, you could create your own Context Manager that extends open() and overloads __enter__():

import os

class OpenCreateDirs(open):
    def __enter__(self, filename, *args, **kwargs):
        file_dir = os.path.dirname(filename)
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)

        super(OpenCreateDirs, self).__enter__(filename, *args, **kwargs)

Then your code becomes:

import os

config_value = 'Foo=Bar'  # Temporary placeholder
config_file_path = os.path.join('/tmp/a/b/c', 'config')

with OpenCreateDirs(config_file_path, 'w') as f:
    f.write(config_value)

The first method to be called when you run with open(...) as f: is open.__enter__(). So by creating directories before calling super(...).__enter__(), you create the directories before attempting to open the file.



来源:https://stackoverflow.com/questions/37711216/recursively-create-directories-prior-to-opening-file-for-writing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!