La fonction os.walk
de Python est un outil puissant pour parcourir récursivement un répertoire et son contenu. En utilisant cette fonction, vous pouvez facilement récupérer tous les sous-répertoires et fichiers d’un répertoire spécifié. Cet article couvre l’utilisation de base de os.walk
, ainsi que des exemples pratiques, afin de vous aider à gérer plus efficacement les tâches impliquant la manipulation des répertoires.
Qu’est-ce que os.walk ?
os.walk
est une fonction incluse dans le module standard os
de Python. Elle permet de parcourir récursivement un répertoire spécifié et génère une liste des fichiers et sous-répertoires dans ce répertoire. En utilisant cette fonction, vous pouvez explorer facilement des structures de répertoires complexes et obtenir des listes de fichiers ou de dossiers, ce qui est très pratique pour les opérations de gestion de répertoires.
Comment fonctionne os.walk
os.walk
fonctionne comme un générateur et renvoie un tuple contenant trois éléments :
- Le chemin du répertoire (
dirpath
)
Indique le chemin du répertoire actuellement exploré. - La liste des sous-répertoires (
dirnames
)
Une liste des noms des sous-répertoires dans le répertoire actuel. - La liste des fichiers (
filenames
)
Une liste des noms des fichiers dans le répertoire actuel.
Caractéristiques
- Parcours récursif: Explore automatiquement les sous-répertoires du répertoire spécifié.
- Ordre: Il est possible de configurer le parcours pour qu’il soit effectué du haut vers le bas ou du bas vers le haut (
topdown=True/False
). - Efficacité: Génère les informations nécessaires à la volée, ce qui permet une gestion efficace de la mémoire.
Applications
- Recherche de fichiers par nom
- Création d’une liste de fichiers avec une extension spécifique
- Calcul de la taille des sous-répertoires
- Automatisation des tâches de sauvegarde et de déplacement
Utilisation de base
En utilisant os.walk
, vous pouvez facilement obtenir les fichiers et dossiers sous un répertoire spécifié. Voici un exemple de code simple pour illustrer son utilisation de base.
Exemple de code
import os
# Spécification du répertoire cible
target_directory = "/path/to/your/directory"
# Parcours du répertoire avec os.walk
for dirpath, dirnames, filenames in os.walk(target_directory):
print(f"Chemin actuel: {dirpath}")
print(f"Sous-répertoires: {dirnames}")
print(f"Fichiers: {filenames}")
print("-" * 40)
Exemple de sortie
Supposons que la structure du répertoire soit la suivante :
/path/to/your/directory
├── file1.txt
├── file2.txt
├── subdir1
│ └── file3.txt
└── subdir2
└── file4.txt
Lorsque vous exécutez os.walk
, vous obtiendrez la sortie suivante :
Chemin actuel: /path/to/your/directory
Sous-répertoires: ['subdir1', 'subdir2']
Fichiers: ['file1.txt', 'file2.txt']
----------------------------------------
Chemin actuel: /path/to/your/directory/subdir1
Sous-répertoires: []
Fichiers: ['file3.txt']
----------------------------------------
Chemin actuel: /path/to/your/directory/subdir2
Sous-répertoires: []
Fichiers: ['file4.txt']
----------------------------------------
Explication
- dirpath: Le chemin du répertoire actuellement exploré.
- dirnames: La liste des sous-répertoires dans le répertoire actuel.
- filenames: La liste des fichiers dans le répertoire actuel.
Remarques
Si le répertoire spécifié n’existe pas, os.walk
générera une erreur. Il est donc conseillé de vérifier préalablement l’existence du répertoire pour éviter ce type d’erreur.
Traitement des fichiers et répertoires séparément
Avec os.walk
, vous pouvez facilement trier les fichiers et les répertoires et appliquer des traitements différents à chacun. Il suffit d’ajouter des conditions de branchement pour réaliser cette distinction.
Exemple de code
Voici un exemple où les fichiers et répertoires sont traités séparément :
import os
# Spécification du répertoire cible
target_directory = "/path/to/your/directory"
# Parcours du répertoire avec traitement séparé des fichiers et des répertoires
for dirpath, dirnames, filenames in os.walk(target_directory):
# Traitement des sous-répertoires
for dirname in dirnames:
subdir_path = os.path.join(dirpath, dirname)
print(f"Répertoire: {subdir_path}")
# Traitement des fichiers
for filename in filenames:
file_path = os.path.join(dirpath, filename)
print(f"Fichier: {file_path}")
Exemple de sortie
Supposons que la structure du répertoire soit la suivante :
/path/to/your/directory
├── file1.txt
├── file2.txt
├── subdir1
│ └── file3.txt
└── subdir2
└── file4.txt
La sortie sera la suivante :
Répertoire: /path/to/your/directory/subdir1
Répertoire: /path/to/your/directory/subdir2
Fichier: /path/to/your/directory/file1.txt
Fichier: /path/to/your/directory/file2.txt
Fichier: /path/to/your/directory/subdir1/file3.txt
Fichier: /path/to/your/directory/subdir2/file4.txt
Explication du code
os.path.join
: Utilisé pour combinerdirpath
etdirname
oufilename
afin de générer des chemins absolus.- Traitement des répertoires (
for dirname in dirnames
): Vous pouvez appliquer des opérations spécifiques aux répertoires (par exemple, obtenir la date de création d’un répertoire). - Traitement des fichiers (
for filename in filenames
): Vous pouvez appliquer des opérations spécifiques aux fichiers (par exemple, obtenir la taille d’un fichier).
Exemples d’applications
- Créer et gérer une liste des sous-répertoires.
- Extraire et traiter des fichiers correspondant à une convention de nommage spécifique.
- Filtrer les fichiers en fonction de leur taille ou de leur date de création.
Recherche de fichiers avec une extension spécifique
En utilisant os.walk
, vous pouvez facilement rechercher des fichiers avec une extension spécifique, comme .txt
ou .jpg
, et extraire uniquement ces fichiers.
Exemple de code
Voici un exemple de code pour rechercher les fichiers avec l’extension .txt
et afficher leur chemin :
import os
# Spécification du répertoire cible
target_directory = "/path/to/your/directory"
# Extension à rechercher
target_extension = ".txt"
# Recherche des fichiers avec l'extension spécifiée
for dirpath, dirnames, filenames in os.walk(target_directory):
for filename in filenames:
if filename.endswith(target_extension):
file_path = os.path.join(dirpath, filename)
print(f"Trouvé: {file_path}")
Exemple de sortie
Supposons que la structure du répertoire soit la suivante :
/path/to/your/directory
├── file1.txt
├── file2.doc
├── subdir1
│ └── notes.txt
└── subdir2
└── image.png
La sortie sera la suivante :
Trouvé: /path/to/your/directory/file1.txt
Trouvé: /path/to/your/directory/subdir1/notes.txt
Explication du code
filename.endswith(target_extension)
: Cette condition renvoie True si le nom de fichier se termine par l’extension spécifiée. Cela permet de filtrer les fichiers selon leur format.os.path.join
: Utilisé pour générer un chemin absolu pour le fichier.
Recherche de plusieurs extensions
Si vous souhaitez rechercher plusieurs extensions, vous pouvez ajuster la condition en conséquence.
# Extensions à rechercher spécifiées dans une liste
target_extensions = [".txt", ".doc"]
for dirpath, dirnames, filenames in os.walk(target_directory):
for filename in filenames:
if filename.endswith(tuple(target_extensions)):
file_path = os.path.join(dirpath, filename)
print(f"Trouvé: {file_path}")
Applications pratiques
- Obtenir la liste des fichiers source dans un projet (par exemple, les fichiers
.py
). - Rechercher et traiter en lot des fichiers d’images spécifiques (par exemple,
.jpg
ou.png
). - Créer des statistiques sur les fichiers selon leur extension.
Limitation de la profondeur de parcours du répertoire
os.walk
explore tous les niveaux d’un répertoire par défaut, mais dans certains cas, vous pouvez souhaiter limiter la recherche à une profondeur spécifique. Pour ce faire, vous pouvez suivre la profondeur actuelle et limiter le traitement en fonction de celle-ci.
Exemple de code
Voici un exemple où la profondeur du répertoire est limitée à 2 :
import os
# Spécification du répertoire cible
target_directory = "/path/to/your/directory"
# Limitation de la profondeur maximale à 2
max_depth = 2
# Exploration avec limitation de la profondeur
for dirpath, dirnames, filenames in os.walk(target_directory):
# Calcul de la profondeur actuelle
current_depth = dirpath.count(os.sep) - target_directory.count(os.sep) + 1
if current_depth > max_depth:
# Ignorer les sous-répertoires si la profondeur maximale est dépassée
del dirnames[:] # Vider la liste dirnames pour ignorer les sous-répertoires
continue
print(f"Profondeur {current_depth}: {dirpath}")
print(f"Sous-répertoires: {dirnames}")
print(f"Fichiers: {filenames}")
print("-" * 40)
Exemple de sortie
Si la structure du répertoire est la suivante :
/path/to/your/directory
├── file1.txt
├── subdir1
│ ├── file2.txt
│ └── subsubdir1
│ └── file3.txt
└── subdir2
└── file4.txt
Le résultat pour une exploration jusqu’à une profondeur de 2 sera le suivant :
Profondeur 1: /path/to/your/directory
Sous-répertoires: ['subdir1', 'subdir2']
Fichiers: ['file1.txt']
----------------------------------------
Profondeur 2: /path/to/your/directory/subdir1
Sous-répertoires: ['subsubdir1']
Fichiers: ['file2.txt']
----------------------------------------
Profondeur 2: /path/to/your/directory/subdir2
Sous-répertoires: []
Fichiers: ['file4.txt']
----------------------------------------
Explication du code
os.sep
: Permet de récupérer le séparateur de répertoire propre au système d’exploitation (par exemple,\\
sous Windows et/
sous Unix).dirpath.count(os.sep)
: Compte le nombre de séparateurs de répertoire dans le chemin actuel, ce qui permet de calculer la profondeur du répertoire.del dirnames[:]
: Vide la liste des sous-répertoires afin d’arrêter l’exploration des sous-répertoires plus profonds.
Applications pratiques
- Explorer uniquement les répertoires de niveau supérieur dans un grand projet.
- Afficher une partie limitée de l’arborescence des répertoires.
- Réduire la charge des opérations disque en limitant l’exploration.
Ignorer les fichiers et répertoires cachés
Lorsque vous parcourez des répertoires, vous pouvez avoir besoin d’ignorer les fichiers et répertoires cachés, généralement ceux qui commencent par un point .
. En filtrant ces éléments avec os.walk
, vous pouvez effectuer des traitements plus efficaces.
Exemple de code
Voici un exemple de code pour ignorer les fichiers et répertoires cachés lors du parcours d’un répertoire :
import os
# Spécification du répertoire cible
target_directory = "/path/to/your/directory"
# Parcours en ignorant les fichiers et répertoires cachés
for dirpath, dirnames, filenames in os.walk(target_directory):
# Ignorer les répertoires cachés
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
# Ignorer les fichiers cachés
visible_files = [f for f in filenames if not f.startswith(".")]
print(f"Chemin actuel: {dirpath}")
print(f"Sous-répertoires: {dirnames}")
print(f"Fichiers: {visible_files}")
print("-" * 40)
Exemple de sortie
Si la structure du répertoire est la suivante :
/path/to/your/directory
├── file1.txt
├── .hidden_file.txt
├── subdir1
│ ├── file2.txt
│ └── .hidden_folder
│ └── file3.txt
└── subdir2
└── file4.txt
Les fichiers et répertoires cachés seront ignorés, et la sortie sera la suivante :
Chemin actuel: /path/to/your/directory
Sous-répertoires: ['subdir1', 'subdir2']
Fichiers: ['file1.txt']
----------------------------------------
Chemin actuel: /path/to/your/directory/subdir1
Sous-répertoires: []
Fichiers: ['file2.txt']
----------------------------------------
Chemin actuel: /path/to/your/directory/subdir2
Sous-répertoires: []
Fichiers: ['file4.txt']
----------------------------------------
Explication du code
- Ignorer les répertoires cachés (
dirnames[:] = ...
): Remplacedirnames
par une liste des répertoires dont les noms ne commencent pas par un point, ce qui empêche l’exploration de ces répertoires. - Ignorer les fichiers cachés (
[f for f in filenames ...]
): Utilise une compréhension de liste pour exclure les fichiers dont les noms commencent par un point.
Remarques
- Si les fichiers ou répertoires sont définis comme « cachés » par des attributs système (surtout sous Windows), ce code ne pourra pas les détecter. Dans ce cas, vous devrez utiliser des modules supplémentaires (par exemple
ctypes
).
Applications pratiques
- Exclure les fichiers de configuration cachés (par exemple,
.gitignore
ou.env
). - Créer une liste de répertoires visibles pour les utilisateurs.
- Nettoyer des jeux de données volumineux en excluant les éléments cachés.
Calcul de la taille d’un répertoire
En utilisant os.walk
, vous pouvez calculer la taille totale d’un répertoire en additionnant la taille de tous les fichiers qu’il contient. Cette méthode est utile pour connaître l’espace de stockage utilisé par un dossier particulier.
Exemple de code
Voici un exemple de code pour calculer la taille totale d’un répertoire :
import os
# Spécification du répertoire cible
target_directory = "/path/to/your/directory"
def calculate_directory_size(directory):
total_size = 0
# Parcours du répertoire
for dirpath, dirnames, filenames in os.walk(directory):
for filename in filenames:
file_path = os.path.join(dirpath, filename)
try:
# Ajout de la taille du fichier
total_size += os.path.getsize(file_path)
except FileNotFoundError:
# Gestion des exceptions si un fichier est supprimé
pass
return total_size
# Calcul de la taille du répertoire
directory_size = calculate_directory_size(target_directory)
# Affichage du résultat (en octets et en Mo)
print(f"Taille du répertoire: {directory_size} octets")
print(f"Taille du répertoire: {directory_size / (1024 ** 2):.2f} Mo")
Exemple de sortie
Si la structure du répertoire est la suivante :
/path/to/your/directory
├── file1.txt (500 octets)
├── subdir1
│ ├── file2.txt (1500 octets)
│ └── file3.txt (3000 octets)
└── subdir2
└── file4.txt (2000 octets)
Le résultat de l’exécution sera :
Taille du répertoire: 7000 octets
Taille du répertoire: 0.01 Mo
Explication du code
os.path.getsize(file_path)
: Permet d’obtenir la taille d’un fichier en octets.- Gestion des exceptions: Si un fichier est supprimé ou inaccessible, l’exception
FileNotFoundError
est capturée pour éviter que le programme ne plante. - Conversion des unités: Convertit la taille en octets en une taille plus lisible, par exemple en Mo.
Calcul de la taille des fichiers avec une extension spécifique
Pour calculer la taille totale des fichiers avec une extension spécifique, vous pouvez modifier le code comme suit :
def calculate_size_by_extension(directory, extension):
total_size = 0
for dirpath, dirnames, filenames in os.walk(directory):
for filename in filenames:
if filename.endswith(extension):
file_path = os.path.join(dirpath, filename)
try:
total_size += os.path.getsize(file_path)
except FileNotFoundError:
pass
return total_size
# Exemple : calcul de la taille totale des fichiers .txt
txt_size = calculate_size_by_extension(target_directory, ".txt")
print(f"Taille des fichiers .txt: {txt_size} octets")
Utilité pratique
- Suivi de l’utilisation de l’espace disque sur un serveur ou un stockage cloud.
- Estimation de la consommation des ressources d’un dossier projet spécifique.
- Assistance pour le nettoyage lors d’un manque d’espace disque.
Création d’une copie de sauvegarde de tous les fichiers
En utilisant os.walk
, vous pouvez parcourir récursivement tous les fichiers d’un répertoire et les copier dans un répertoire de sauvegarde, créant ainsi une copie de sauvegarde complète du répertoire tout en préservant sa structure.
Exemple de code
Voici un exemple de code pour copier tous les fichiers dans un répertoire de sauvegarde :
import os
import shutil
# Répertoires source et de sauvegarde spécifiés
source_directory = "/path/to/your/source_directory"
backup_directory = "/path/to/your/backup_directory"
def backup_files(source, backup):
for dirpath, dirnames, filenames in os.walk(source):
# Calcul du chemin de sauvegarde
relative_path = os.path.relpath(dirpath, source)
backup_path = os.path.join(backup, relative_path)
# Création du répertoire de sauvegarde
os.makedirs(backup_path, exist_ok=True)
for filename in filenames:
source_file = os.path.join(dirpath, filename)
backup_file = os.path.join(backup_path, filename)
try:
# Copie du fichier
shutil.copy2(source_file, backup_file)
print(f"Copié: {source_file} -> {backup_file}")
except Exception as e:
print(f"Échec de la copie de {source_file}: {e}")
# Exécution de la sauvegarde
backup_files(source_directory, backup_directory)
Exemple de sortie
Si la structure du répertoire source est la suivante :
/path/to/your/source_directory
├── file1.txt
├── subdir1
│ ├── file2.txt
│ └── file3.txt
└── subdir2
└── file4.txt
La structure du répertoire de sauvegarde sera la suivante :
/path/to/your/backup_directory
├── file1.txt
├── subdir1
│ ├── file2.txt
│ └── file3.txt
└── subdir2
└── file4.txt
Explication du code
os.makedirs(backup_path, exist_ok=True)
: Crée le répertoire de sauvegarde de manière récursive. Le paramètreexist_ok=True
permet de ne pas générer d’erreur si le répertoire existe déjà.os.path.relpath(dirpath, source)
: Récupère le chemin relatif du répertoire source pour créer le répertoire de sauvegarde correspondant.shutil.copy2(source_file, backup_file)
: Copie le fichier ainsi que ses métadonnées, comme les timestamps.
Remarques
- Liens symboliques:
shutil.copy2
copie les liens symboliques comme des fichiers normaux. Si vous souhaitez conserver les liens, un traitement supplémentaire est nécessaire. - Capacité disque: Assurez-vous que le répertoire de sauvegarde dispose de suffisamment d’espace disque.
- Permissions d’accès: Vous devez avoir les permissions nécessaires pour accéder aux fichiers source.
Applications pratiques
- Sauvegarde de fichiers spécifiques, comme ceux avec une extension particulière (par exemple,
if filename.endswith(".txt")
). - Création d’un journal de sauvegarde: enregistrer les fichiers copiés dans un fichier journal.
- Sauvegarde différentielle: Copiez uniquement les fichiers modifiés en comparant les timestamps ou les hachages.
Résumé
Dans cet article, nous avons exploré comment utiliser os.walk
pour parcourir récursivement un répertoire et ses fichiers en Python. Nous avons abordé son utilisation de base, ainsi que de nombreuses applications pratiques, telles que la recherche de fichiers par extension, le calcul de la taille des répertoires, l’ignorance des fichiers et répertoires cachés, et la création de sauvegardes automatiques.
Grâce à sa flexibilité, os.walk
est un outil puissant pour automatiser les tâches liées à la gestion des répertoires et améliorer l’efficacité du travail.