Обратный вызов Ignore для python shutil.copytree() не принимает полный путь
Я хотел бы указать полные пути к игнорируемым файлам и каталогам при вызове shutil.copytree(). Что-то вроде
def my_ignore(dir, files):
# return ["exclude.file"] # working
return ["/full_path_to/exclude.file"] # Not working
shutil.copytree(src, dest, ignore=my_ignore)
После этого исключенный файл все еще там, если я не верну просто имя файла вместо полного пути. Дело в том, что я действительно хочу настроить конкретный файл вместо всех совпадающих имен файлов в разных каталогах.
Я упомянул ряд вопросов, таких как: Как написать функцию обратного вызова для игнорирования в shutil.copytree
Фильтровать каталог при использовании shutil.copytree?
Но ни один из ответов не работает. Похоже, что ловушка игнорирования может возвращать только глобальный стиль, и любой созданный полный путь не будет работать.
Я что-то пропустил?
2 ответа
ignore
действительно должен возвращать только имена файлов, которые игнорируются. Тем не менее, функция вызывается для каждого каталога shutil.copytree()
посещения; Вы можете игнорировать файлы в каталоге.
Если у вас есть полный путь к файлу, который нужно игнорировать, сопоставьте его с первым параметром, переданным вашему ignore
функция; это полный путь к этому каталогу:
def my_ignore(dir, files):
if dir == '/full_path_to':
return {"exclude.file"}
Я возвращаю набор здесь; установить членство тестирования быстрее, чем со списком.
Если у вас есть предопределенный набор путей, которые нужно игнорировать, проанализируйте их в словаре; ключи - это путь к каталогу, значения наборов имен файлов в этом пути:
from collections import defaultdict
to_ignore = defaultdict(set)
for path in ignored_paths:
dirname, filename = os.path.split(path)
to_ignore[dirname].add(filename)
def my_ignore(src, files):
return to_ignore.get(src, set())
Это не волшебство. copytree()
копирует содержимое одного каталога за раз, и он специально ищет имена файлов в списке игнорирования, который вы возвращаете. Полный путь никогда не является именем файла, поэтому он никогда не совпадает.
Тем не менее dir
Параметр поможет вам сделать то, что вы хотите:
def my_ignore(dir, files):
if dir == "/full/path/to":
return ["exclude.file"]
else:
return []