web-dev-qa-db-fra.com

Python shutil copytree: utilisez la fonction ignore pour conserver des types de fichiers spécifiques

J'essaie de comprendre comment copier des dessins CAD (".dwg", ".dxf) d'un répertoire source avec des sous-dossiers vers un répertoire de destination et en maintenant le répertoire d'origine et la structure des sous-dossiers.

  • Annuaire d'origine: H:\Tanzania ...\Bagamoyo_Single_line.dwg
  • Répertoire source: H:\CAD\Tanzania ...\Bagamoyo_Single_line.dwg

J'ai trouvé la réponse suivante de @ martinea dans le message suivant: Python Factory Function

from fnmatch import fnmatch, filter
from os.path import isdir, join
from shutil import copytree

def include_patterns(*patterns):
    """Factory function that can be used with copytree() ignore parameter.

    Arguments define a sequence of glob-style patterns
    that are used to specify what files to NOT ignore.
    Creates and returns a function that determines this for each directory
    in the file hierarchy rooted at the source directory when used with
    shutil.copytree().
    """
    def _ignore_patterns(path, names):
        keep = set(name for pattern in patterns
                            for name in filter(names, pattern))
        ignore = set(name for name in names
                        if name not in keep and not isdir(join(path, name)))
        return ignore
    return _ignore_patterns

# sample usage

copytree(src_directory, dst_directory,
         ignore=include_patterns('*.dwg', '*.dxf'))

Mis à jour: 18:21. Le code suivant fonctionne comme prévu, sauf que je voudrais ignorer les dossiers qui ne contiennent aucun include_patterns ('. Dwg', '. Dxf ')

11
Peter Wilson

shutil contient déjà une fonction ignore_pattern, vous n'avez donc pas à fournir le vôtre. Directement à partir de documentation :

from shutil import copytree, ignore_patterns

copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

Cela copiera tout sauf .pyc fichiers et fichiers ou répertoires dont le nom commence par tmp.

C'est un peu délicat (et pas strictement nécessaire) d'expliquer ce qui se passe: ignore_patterns renvoie une fonction _ignore_patterns comme valeur de retour, cette fonction est insérée dans copytree en tant que paramètre, et copytree appelle cette fonction si nécessaire, vous n'avez donc pas besoin de savoir ou de savoir comment appeler cette fonction _ignore_patterns. Cela signifie simplement que vous pouvez exclure certains fichiers de fichiers inutiles (comme *.pyc) d'être copié. Le fait que le nom de la fonction _ignore_patterns commence par un trait de soulignement indique que cette fonction est un détail d'implémentation que vous pouvez ignorer.

copytree s'attend à ce que le dossier destination n'existe pas encore. Ce n'est pas un problème que ce dossier et ses sous-dossiers existent une fois que copytree commence à fonctionner, copytree sait comment gérer cela.

Maintenant include_patterns est écrit pour faire le contraire: ignorer tout ce qui n'est pas explicitement inclus. Mais cela fonctionne de la même façon: vous l'appelez simplement, il retourne une fonction sous le capot, et coptytree sait quoi faire avec cette fonction:

copytree(source, destination, ignore=include_patterns('*.dwg', '*.dxf'))
18
Jan