如何用Python将整个文件夹复制到已有目录中?
在一个包含名为 bar
的文件夹(里面有一个或多个文件)和名为 baz
的文件夹(同样里面有一个或多个文件)的目录下运行以下代码。确保没有名为 foo
的文件夹。
import shutil
shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo')
这段代码会失败,错误信息是:
$ python copytree_test.py
Traceback (most recent call last):
File "copytree_test.py", line 5, in <module>
shutil.copytree('baz', 'foo')
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/shutil.py", line 110, in copytree
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/os.py", line 172, in makedirs
OSError: [Errno 17] File exists: 'foo'
我希望这个操作的效果和我直接输入以下内容是一样的:
$ mkdir foo
$ cp bar/* foo/
$ cp baz/* foo/
我需要用 shutil.copy()
把 baz
里的每个文件复制到 foo
吗?(在我已经用 shutil.copytree()
把 'bar' 的内容复制到 'foo' 之后)?还是有更简单或更好的方法呢?
15 个回答
159
Python 3.8 新增了一个叫做 dirs_exist_ok
的参数,这个参数是用在shutil.copytree
函数里的:
这个函数可以把一个目录及其所有内容从 src 复制到一个叫 dst 的目录,并返回目标目录。如果 dirs_exist_ok 设置了,就可以控制在目标目录 dst 或者它的上级目录已经存在的情况下,是否抛出错误。
所以,在 Python 3.8 及以上版本中,这样写应该是可以的:
import shutil
shutil.copytree('bar', 'foo') # Will fail if `foo` exists
shutil.copytree('baz', 'foo', dirs_exist_ok=True) # Fine
449
这里有一个解决方案,它是标准库的一部分:
from distutils.dir_util import copy_tree
copy_tree("/a/b/c", "/x/y/z")
你可以看看这个类似的问题。
260
标准的 shutil.copytree
方法有一些限制,看起来很随意,让人觉得烦人。这里有个解决办法:
import os, shutil
def copytree(src, dst, symlinks=False, ignore=None):
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
shutil.copytree(s, d, symlinks, ignore)
else:
shutil.copy2(s, d)
需要注意的是,这个解决办法和标准的 copytree
方法并不完全一致:
- 它对源目录的根目录不支持
symlinks
(符号链接)和ignore
(忽略)参数; - 在源目录的根目录出现错误时,它不会抛出
shutil.Error
错误; - 如果在复制子目录时出现错误,它会只针对那个子目录抛出
shutil.Error
,而不是尝试复制其他子目录并抛出一个合并的shutil.Error
。