Considérez ce scénario:
#!/usr/bin/env python # - * - codage: utf-8 - * - import os walk = os.walk ('/ home') pour root, dirs, files in walk: pour chemin dans répertoire + fichiers: print os.path.join (root, chemin d'accès) pour root, répertoires, fichiers de la promenade: pour chemin dans répertoire + fichiers: print os.path.join (root, chemin d'accès)
Je sais que cet exemple est un peu redondant, mais vous devriez considérer que nous devons utiliser les mêmes données walk
plusieurs fois. J'ai un scénario de référence et l'utilisation des mêmes données walk
est obligatoire pour obtenir des résultats utiles.
J'ai essayé walk2 = walk
de cloner et d'utiliser à la deuxième itération, mais cela n'a pas fonctionné. La question est ... Comment puis-je le copier? Est-ce jamais possible?
Merci d'avance.
Vous pouvez utiliser itertools.tee()
:
walk, walk2 = itertools.tee(walk)
Notez que cela pourrait "nécessiter un stockage supplémentaire important", comme le souligne la documentation.
Définir une fonction
def walk_home():
for r in os.walk('/home'):
yield r
Ou même cela
def walk_home():
return os.walk('/home')
Les deux sont utilisés comme ceci:
for root, dirs, files in walk_home():
for pathname in dirs+files:
print os.path.join(root, pathname)
Ceci est un bon cas d'utilisation pour functools.partial()
Pour créer une usine-générateur rapide:
from functools import partial
import os
walk_factory = partial(os.walk, '/home')
walk1, walk2, walk3 = walk_factory(), walk_factory(), walk_factory()
Il est difficile de décrire ce que functools.partial()
fait avec des mots humains, mais voici ce à quoi il sert.
Il partial remplit les paramètres de fonction sans exécuter cette fonction. Par conséquent, il agit comme une usine de fonction/générateur.
Cette réponse vise à développer/développer ce que les autres réponses ont exprimé. La solution variera nécessairement en fonction de ce que exactement vous souhaitez atteindre.
Si vous souhaitez parcourir plusieurs fois le même résultat exact de os.walk
, vous devrez initialiser une liste à partir des éléments de os.walk
iterable (c'est-à-dire _walk = list(os.walk(path))
).
Si vous devez garantir que les données restent les mêmes, c'est probablement votre seule option. Cependant, il existe plusieurs scénarios dans lesquels cela n'est ni possible ni souhaitable.
list()
ne sera pas possible si la taille de la sortie est suffisante (par exemple, si vous tentez de list()
un système de fichiers entier risque de figer votre ordinateur).list()
n'est pas souhaitable si vous souhaitez acquérir des données "fraîches" avant chaque utilisation.Dans le cas où list()
ne convient pas, vous devrez exécuter votre générateur à la demande. Notez que les générateurs s'éteignent après chaque utilisation, ce qui pose un léger problème. Pour "réexécuter" votre générateur plusieurs fois, vous pouvez utiliser le modèle suivant:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
class WalkMaker:
def __init__(self, path):
self.path = path
def __iter__(self):
for root, dirs, files in os.walk(self.path):
for pathname in dirs + files:
yield os.path.join(root, pathname)
walk = WalkMaker('/home')
for path in walk:
pass
# do something...
for path in walk:
pass
Le modèle de conception susmentionné vous permettra de garder votre code au sec.