Comment est-ce que je limite os.walk
pour ne renvoyer que des fichiers dans le répertoire que je fournis?
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
return outputList
Utilisez la fonction walklevel
.
import os
def walklevel(some_dir, level=1):
some_dir = some_dir.rstrip(os.path.sep)
assert os.path.isdir(some_dir)
num_sep = some_dir.count(os.path.sep)
for root, dirs, files in os.walk(some_dir):
yield root, dirs, files
num_sep_this = root.count(os.path.sep)
if num_sep + level <= num_sep_this:
del dirs[:]
Cela fonctionne comme os.walk
, mais vous pouvez lui transmettre un paramètre level
qui indique la profondeur de la récursivité.
N'utilisez pas os.walk.
Exemple:
import os
root = "C:\\"
for item in os.listdir(root):
if os.path.isfile(os.path.join(root, item)):
print item
Je pense que la solution est en réalité très simple.
utilisation
break
pour ne faire que la première itération de la boucle for, il doit y avoir un moyen plus élégant.
for root, dirs, files in os.walk(dir_name):
for f in files:
...
...
break
...
La première fois que vous appelez os.walk, il renvoie des tulipes pour le répertoire actuel, puis boucle le contenu du répertoire suivant.
Prenez le script original et ajoutez simplement un break .
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
break
return outputList
La suggestion d'utiliser listdir
est bonne. La réponse directe à votre question dans Python 2 est root, dirs, files = os.walk(dir_name).next()
.
La syntaxe équivalente de Python 3 est root, dirs, files = next(os.walk(dir_name))
Vous pouvez utiliser os.listdir()
qui renvoie une liste de noms (pour les fichiers et les répertoires) dans un répertoire donné. Si vous devez faire la distinction entre les fichiers et les répertoires, appelez os.stat()
pour chaque nom.
Si vous avez des exigences plus complexes que celle du répertoire principal (par exemple, ignorer les répertoires VCS, etc.), vous pouvez également modifier la liste des répertoires pour empêcher os.walk de les parcourir de manière récurrente.
c'est à dire:
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
dirs[:] = [d for d in dirs if is_good(d)]
for f in files:
do_stuff()
Remarque: veillez à modifier la liste au lieu de la renvoyer. De toute évidence, os.walk ne connaît pas la reconnexion externe.
La même idée avec listdir
, mais plus courte:
[f for f in os.listdir(root_dir) if os.path.isfile(os.path.join(root_dir, f))]
Envie de jeter mes 2 pence.
baselevel = len(rootdir.split("\\"))
for subdirs, dirs, files in os.walk(rootdir):
curlevel = len(subdirs.split("\\"))
if curlevel <= baselevel + 1:
[do stuff]
En Python 3, j'ai pu faire ceci:
import os
dir = "/path/to/files/"
#List all files immediately under this folder:
print ( next( os.walk(dir) )[2] )
#List all folders immediately under this folder:
print ( next( os.walk(dir) )[1] )
for path, dirs, files in os.walk('.'):
print path, dirs, files
del dirs[:] # go only one level deep
Vous pouvez également faire ce qui suit:
for path, subdirs, files in os.walk(dir_name):
for name in files:
if path == ".": #this will filter the files in the current directory
#code here
Depuis Python 3.5 , vous pouvez utiliser os.scandir
au lieu de os.listdir
. Au lieu de chaînes, vous obtenez un itérateur de DirEntry
objets en retour. De la docs:
L'utilisation de
scandir()
au lieu delistdir()
peut considérablement améliorer les performances du code qui a également besoin d'informations de type ou d'attributs de fichier, car les objetsDirEntry
exposent ces informations si le système d'exploitation les fournit lors de l'analyse d'un répertoire. Toutes les méthodesDirEntry
peuvent effectuer un appel système, maisis_dir()
etis_file()
ne requièrent généralement qu'un appel système pour les liens symboliques;DirEntry.stat()
nécessite toujours un appel système sous Unix mais un seul pour les liens symboliques sous Windows.
Vous pouvez accéder au nom de l'objet via _DirEntry.name
_ qui est alors équivalent à la sortie de _os.listdir
_
le dossier racine change pour chaque répertoire trouvé par os.walk. Je résous que vérifier si root == répertoire
def _dir_list(self, dir_name, whitelist):
outputList = []
for root, dirs, files in os.walk(dir_name):
if root == dir_name: #This only meet parent folder
for f in files:
if os.path.splitext(f)[1] in whitelist:
outputList.append(os.path.join(root, f))
else:
self._email_to_("ignore")
return outputList
Voici comment je l'ai résolu
if recursive:
items = os.walk(target_directory)
else:
items = [next(os.walk(target_directory))]
...
créer une liste d'exclusions, utilisez fnmatch pour ignorer la structure de répertoires et effectuer le processus
excludes= ['a\*\b', 'c\d\e']
for root, directories, files in os.walk('Start_Folder'):
if not any(fnmatch.fnmatch(nf_root, pattern) for pattern in excludes):
for root, directories, files in os.walk(nf_root):
....
do the process
....
idem que pour 'comprend':
if **any**(fnmatch.fnmatch(nf_root, pattern) for pattern in **includes**):
Il y a un problème lors de l'utilisation de listdir. Os.path.isdir (identifiant) doit être un chemin absolu. Pour choisir les sous-répertoires que vous faites:
for dirname in os.listdir(rootdir):
if os.path.isdir(os.path.join(rootdir, dirname)):
print("I got a subdirectory: %s" % dirname)
L'alternative consiste à accéder au répertoire pour effectuer les tests sans os.path.join ().
Vous pouvez utiliser cet extrait
for root, dirs, files in os.walk(directory):
if level > 0:
# do some stuff
else:
break
level-=1
Pourquoi ne pas simplement utiliser une range
et os.walk
combinés avec la Zip
? N'est-ce pas la meilleure solution, mais fonctionnerait aussi.
Par exemple, comme ceci:
# your part before
for count, (root, dirs, files) in Zip(range(0, 1), os.walk(dir_name)):
# logic stuff
# your later part
Fonctionne pour moi sur Python 3.
Aussi: Une break
est plus simple aussi. (Regardez la réponse de @Pieter)