How can I create directories recursively?
有没有python方法可以递归地创建目录?我有这条路:
我想创建
1
| /home/dail/first/second/third |
我可以递归地执行,还是必须创建一个接一个的目录?
同样的事情:
chmod和chown我可以在没有为每个文件/dir分配权限的情况下递归执行吗?
- superset:还要检查是否存在:stackoverflow.com/questions/600268/…
- 从字符串动态创建文件夹树的python可能重复
你需要的是os.makedirs。对于chmod或chown,您必须使用os.walk,并自己在每个文件/dir上使用它。
- 具体来说:os.makedirs(os.path.join("/home/dail","first","second","third"))
- 注:exist_ok=True方便省去每次都要先检查是否存在的麻烦。
- 注意,只有在python 3.2中添加了exist_ok参数。
一个非常古老的问题的新答案:
从python 3.2开始,您可以这样做:
1 2 3
| import os
path = '/home/dail/first/second/third'
os.makedirs(path, exist_ok=True) |
多亏了exist_ok标志,如果目录存在(取决于您的需要….),这甚至不会抱怨。
从python 3.4(包括pathlib模块)开始,您可以这样做:
1 2 3
| from pathlib import Path
path = Path('/home/dail/first/second/third')
path.mkdir(parents=True) |
从python 3.5开始,mkdir也有一个exist_ok标志-如果目录存在,将其设置为True将不会引发异常:
1
| path.mkdir(parents=True, exist_ok=True) |
- 哇,非常好的描述和多个选项可以处理多个Python版本。非常感谢!
下面是我的实现,供您参考:
1 2 3 4 5 6
| 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) |
希望这有帮助!
- 如果第一个文件夹不存在,此函数将导致堆栈溢出(if not os.path.exists(sub_path)始终为true并调用自身)。但只要第一个目录存在,这似乎是有效的。
我同意cat plus的回答。但是,如果您知道这只会在类Unix操作系统上使用,那么您可以对shell命令mkdir、chmod和chown使用外部调用。确保传递额外的标志以递归地影响目录:
1 2 3 4 5 6 7 8 9 10 11
| >>> 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. |
edit i最初使用的是commands,这是一个糟糕的选择,因为它不受欢迎并且容易受到注入攻击。(例如,如果用户提供了创建名为first/;rm -rf --no-preserve-root /;的目录的输入,则可能会删除所有目录)。
编辑2如果您使用的是小于2.7的python,请使用check_call而不是check_output。详见subprocess文件。
- 有一个问题,来自docs的commands模块:自2.6版以来已弃用:在python 3.0中删除了commands模块。请改用子流程模块。
- 答:谢谢。仍在使用python2.6,没有注意到。将很快进行编辑。
- 但那不是Python,它是一个shell脚本!如果您可以用Python编写一个非常简单的解决方案,甚至是可移植的,那么就这样做。;)
- @罗斯:我百分之百地同意,它的python调用*nix shell命令,而且不可移植(我是这么说的)。但我经常发现自己在编写只在自己的Linux设备上使用的快速python脚本。对于这些目的,调用shell命令可能更简单,因为您可以使用标志(例如-r而不是walkdouble for loop--(每个walked dir中的文件的第二个循环))来完成所需的任务。当然,我可以用bash编写它们,但我觉得python的语法很方便(很容易定义函数/类),而且访问所有命令行标志对我来说也很方便。
- 如果可以直接进行,分叉总是一个坏主意。
- @Dothebart我同意分叉通常是个坏主意,而且会有更多的开销。但区别是几毫秒(因此,除非您要创建数千个目录或者在一个非常资源紧张的系统上——然后您可能需要重新考虑python)。有时,一个熟悉的shell命令在一行中执行您想要的操作,比使用内置较少的python命令(例如,python的os.chmod和os.chown)复制python中的功能更方便。说分叉总是不好似乎是一种过早的优化。
- 看看Pyrd模块并重新思考。现在提出的解决方案值得更多的关注——那是我投了赞成票,这是反对票。
- 我没有看到EDOCX1(一个围绕循环数据库工具和现有的python绑定的方便包装器)对这个讨论的意义。根据其pypi页面,该模块的一半只是一个面向对象的接口,用于使用Popen调用二进制文件(即"分叉",您说过"总是一个坏主意")。(Now, with PyRRD, there are two additional ways to use RRDTool from Python: an object-oriented interface that wraps system calls (Popen) to the rrdtool binary号)。
- python的子进程模块可以安全地使用(不使用shell=True),并且在您已经熟悉shell命令来完成任务时非常有用,这是一种您不介意用shell脚本完成的任务(也就是说,您不需要优化每个命令几毫秒的差异)。我真的不在乎你投了低票(现在已经锁定了),尽管我不同意这是一个"明显的,也许是危险的错误的答案",应该投低票。
尝试使用os.makedirs:
1 2 3 4 5 6 7 8
| import os
import errno
try:
os.makedirs(<path>)
except OSError as e:
if errno.EEXIST != e.errno:
raise |
- 欢迎使用堆栈溢出!感谢您提供这段代码片段,它可以提供一些即时帮助。一个恰当的解释可以通过说明为什么这是解决这个问题的好方法而大大提高它的教育价值,并且可以使它对将来有相似但不完全相同问题的读者更有用。请编辑您的答案以添加解释,并指出哪些限制和假设适用。
- 我会说这个答案对于python 2.x是正确的,因为它正确地处理错误,并且不会两次要求文件系统输入路径(与os.path.exists方法相同)。