如何递归创建目录?

Dai*_*ail 129 python

是否有Python方法以递归方式创建目录?我有这条道路:

/home/dail/
Run Code Online (Sandbox Code Playgroud)

我想创造

/home/dail/first/second/third
Run Code Online (Sandbox Code Playgroud)

我可以递归地执行此操作,还是必须在另一个目录之后创建一个目录?

同样的事情:

我可以递归地执行chmodchown而不为每个文件/目录分配权限吗?

Cat*_*lus 200

os.makedirs是你需要的.对于chmodchown你将不得不使用os.walk,并用它在每一个文件/目录自己.

  • 请注意,`exist_ok`参数仅在Python 3.2中添加 (25认同)
  • 注意,`exist_ok = True`可以方便地保存,每次都要检查它是否存在. (12认同)
  • 具体来说:os.makedirs(os.path.join("/ home/dail","first","second","third")) (7认同)

hir*_*ist 138

一个非常古老的问题的新答案:

从python 3.2开始你可以这样做:

import os
path = '/home/dail/first/second/third'
os.makedirs(path, exist_ok=True)
Run Code Online (Sandbox Code Playgroud)

感谢exist_ok标志,如果目录存在,这甚至都不会抱怨(取决于你的需要......).


从python 3.4(包括pathlib模块)开始,你可以这样做:

from pathlib import Path
path = Path('/home/dail/first/second/third')
path.mkdir(parents=True)
Run Code Online (Sandbox Code Playgroud)

从python 3.5开始mkdir还有一个exist_ok标志 - True如果目录存在,将其设置为不会引发异常:

path.mkdir(parents=True, exist_ok=True)
Run Code Online (Sandbox Code Playgroud)

  • @Hamed_gibago 你甚至不需要使用 `pathlib` 模块。[`os.makedirs`](https://docs.python.org/3/library/os.html#os.makedirs) 本身是递归的...... (3认同)
  • 好一个。`pathlib` 对我有用。 (3认同)
  • 感谢帮助。我总是使用 os.mkdir ,它不会产生孙子和更多嵌套的子代。os.makedirs 刚刚解决了我的问题 (2认同)

dr *_*bob 6

我同意Cat Plus Plus的回答.但是,如果你知道这只会在类Unix操作系统中使用,您可以使用外部调用的shell命令mkdir,chmodchown.确保传递额外的标志以递归地影响目录:

>>> import subprocess
>>> subprocess.check_output(['mkdir', '-p', 'first/second/third']) 
# Equivalent to running 'mkdir -p first/second/third' in a shell (which creates
# parent directories if they do not yet exist).

>>> subprocess.check_output(['chown', '-R', 'dail:users', 'first'])
# Recursively change owner to 'dail' and group to 'users' for 'first' and all of
# its subdirectories.

>>> subprocess.check_output(['chmod', '-R', 'g+w', 'first'])
# Add group write permissions to 'first' and all of its subdirectories.
Run Code Online (Sandbox Code Playgroud)

编辑我最初使用commands,这是一个糟糕的选择,因为它被弃用,容易受到注入攻击.(例如,如果用户提供输入以创建调用的目录first/;rm -rf --no-preserve-root /;,则可能会删除所有目录).

编辑2如果您使用的Python小于2.7,请使用check_call而不是check_output.有关详细信息,请参阅subprocess文档

  • 但这不是 Python,它是一个 shell 脚本!如果您可以用 Python 编写一个非常简单甚至可移植的解决方案,那就这样做吧。;) (3认同)

小智 5

以下是我的实现供您参考:

def _mkdir_recursive(self, path):
    sub_path = os.path.dirname(path)
    if not os.path.exists(sub_path):
        self._mkdir_recursive(sub_path)
    if not os.path.exists(path):
        os.mkdir(path)
Run Code Online (Sandbox Code Playgroud)

希望这有帮助!

  • 如果第一个文件夹不存在,则此函数将导致堆栈溢出(如果不是os.path.exists(sub_path)`将始终为true并调用自身).但只要第一个目录存在,这似乎是有效的. (4认同)

小智 5

尝试使用os.makedirs

import os
import errno

try:
    os.makedirs(<path>)
except OSError as e:
    if errno.EEXIST != e.errno:
        raise
Run Code Online (Sandbox Code Playgroud)

  • 欢迎使用Stack Overflow!感谢您提供此代码段,它可能会立即提供帮助。适当的解释[会大大改善](//meta.stackexchange.com/q/114762)其教育价值,方法是显示*为什么*这是解决该问题的好方法,并将使其对类似的未来读者更有用,但问题并不完全相同。请[编辑]您的答案以添加解释,并指出适用的限制和假设。 (3认同)