gpt4 book ai didi

python - 使用特殊情况处理在 Python 中实现递归复制

转载 作者:太空宇宙 更新时间:2023-11-04 01:29:49 25 4
gpt4 key购买 nike

我想在 Python 中实现 cp -r 的一个版本,它以特殊方式处理某些目录。如果您执行 mycp.py -r indir outdir,我希望将 indir 及其所有文件/子目录准确复制到 outdir ,除了某些文件名。在 Python 中执行此操作最便携的方法是什么?

例子:我有这个目录结构:

dir1/
file1
dir2/
dir3/
specialdir/
myfile.bar

file1 是一个文件,specialdir 是一个包含文件 myfile.bar 的目录。我想复制 dir1 及其所有内容,但要特别处理其中包含 *.bar 文件的目录。在这种情况下,只有 specialdir 符合条件。我想 mycopy 复制所有 dir1 但用它们自己的压缩版本替换任何特殊目录。在上面的示例中,这意味着按原样复制 dir1,但将 specialdir 替换为可能包含 的处理版本的 specialdir.zip myfile.bar.

我尝试遵循以下建议,但我不确定如何处理复制:

import os
import shutil

SPECIAL_DIRS = []

def is_special_dir(path, dirnames):
"""directories are special if they have .bar files"""
special_dirs = []
for d in dirnames:
d = os.path.join(path, d)
if os.path.isdir(d):
files_in_d = os.listdir(d)
for f in files_in_d:
if f.endswith(".bar"):
# directory is special if it contains
# .bar files
special_dirs.append(d)
SPECIAL_DIRS.extend(special_dirs)
return special_dirs

def my_copy(indir, outdir):
shutil.copytree(indir, outdir, ignore=is_special_dir)
print "Found special dirs: ", SPECIAL_DIRS

# make a copy of dir1 but handle special directories
# differently
my_copy("dir1", "copy_dir1")

如果我尝试它,它会正确检测到特殊目录:

$ copy_test.py
Found special dirs: ['dir1/dir2/specialdir']

我怎样才能让它在 copy_dir1 的正确对应位置插入 specialdir?我希望 copy_dir1(目标目录)与 dir1(源目录)具有完全相同的结构,除了对包含 .bar 的目录进行特殊处理 文件。

最佳答案

听起来你想要shutil.copytree利用忽略参数:

If ignore is given, it must be a callable that will receive as its arguments the directory being visited by copytree(), and a list of its contents, as returned by os.listdir(). Since copytree() is called recursively, the ignore callable will be called once for each directory that is copied. The callable must return a sequence of directory and file names relative to the current directory (i.e. a subset of the items in its second argument); these names will then be ignored in the copy process. 'ignore_patterns()' can be used to create such a callable that ignores names based on glob-style patterns.

所以这样的事情应该可行:

def what_to_ignore(path,names):
if is_special(path):
# process names here returning any or all to ignore

shutil.copytree(indir,outdir,ignore=what_to_ignore)

编辑扩展问题和示例

这是一个例子。简化的忽略功能仍然创建一个空的特殊目录,但在执行特殊 zip 复制之前很容易删除。我还嵌套了特殊函数,因此 my_copy 可以多次使用,而无需依赖使用全局变量。压缩是对用户的练习:

import fnmatch
import shutil
import os

def my_copy(indir, outdir):

special = []

def is_special_dir(path, names):
"""directories are special if they have .bar files"""
if fnmatch.filter(names,'*.bar'):
special.append(path)
return names
return []

shutil.copytree(indir, outdir, ignore=is_special_dir)
print('Found special dirs:',special)

for src in special:
rel = os.path.relpath(src,indir)
dst = os.path.join(outdir,rel)
os.rmdir(dst)
print('Zip "{}" to "{}.zip"'.format(src,dst))

my_copy('dir1','dira')
my_copy('dir1','dirb')

输出

Found special dirs: ['dir1\\specialdir']
Zip "dir1\specialdir" to "dira\specialdir.zip"
Found special dirs: ['dir1\\specialdir']
Zip "dir1\specialdir" to "dirb\specialdir.zip"

关于python - 使用特殊情况处理在 Python 中实现递归复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14668206/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com