Obtenir l’emplacement (chemin) d’un fichier en cours d’exécution en Python : __file__.

Affaires

Pour obtenir l'emplacement (chemin) d'un fichier de script en cours d'exécution en Python, utilisez __file__. Ceci est utile pour charger d'autres fichiers en fonction de l'emplacement du fichier en cours d'exécution.

Jusqu'à Python 3.8, __file__ renvoie le chemin spécifié lors de l'exécution de la commande python (ou de la commande python3 dans certains environnements). Si un chemin relatif est spécifié, le chemin relatif est renvoyé ; si un chemin absolu est spécifié, le chemin absolu est renvoyé.

Dans Python 3.9 et les versions ultérieures, le chemin absolu est renvoyé indépendamment du chemin spécifié au moment de l'exécution.

Les contenus suivants sont expliqués.

  • os.getcwd(),__file__
  • Obtenir le nom du fichier et le nom du répertoire du fichier en cours d'exécution.
  • Obtenir le chemin absolu du fichier en cours d'exécution.
  • Lit d'autres fichiers en fonction de l'emplacement du fichier en cours d'exécution.
  • Déplace le répertoire courant vers le répertoire du fichier en cours d'exécution.
  • Le même traitement peut être effectué quel que soit le répertoire courant au moment de l'exécution.

Voir l'article suivant pour des informations sur l'obtention et la modification du répertoire courant (répertoire de travail).

Notez que __file__ ne peut pas être utilisé dans Jupyter Notebook (.ipynb).
Le répertoire où se trouve .ipynb sera exécuté comme répertoire courant, indépendamment du répertoire où Jupyter Notebook est lancé.
Il est possible d'utiliser os.chdir() dans le code pour changer le répertoire courant.

os.getcwd() et __file__.

Sous Windows, vous pouvez utiliser la commande dir au lieu de pwd pour vérifier le répertoire courant.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

Créez un fichier script Python (file_path.py) avec le contenu suivant dans le niveau inférieur (data\src).

import os

print('getcwd:      ', os.getcwd())
print('__file__:    ', __file__)

Exécutez la commande python (ou la commande python3 dans certains environnements) en spécifiant le chemin d'accès au fichier script.

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py

Le chemin absolu du répertoire courant peut être obtenu avec os.getcwd(). Vous pouvez également utiliser __file__ pour obtenir le chemin spécifié par la commande python3.

Jusqu'à Python 3.8, __file__ contient le chemin spécifié dans la commande python (ou python3). Dans l'exemple ci-dessus, le chemin relatif est renvoyé parce qu'il est relatif, mais le chemin absolu est renvoyé s'il est absolu.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py

Python 3.9 et les versions ultérieures renvoient le chemin d'accès absolu au __fichier__, indépendamment du chemin d'accès spécifié dans la commande python (ou python3).

Dans l'exemple suivant, nous allons ajouter le code au même fichier script (file_path.py) en Python 3.7 et l'exécuter relativement au répertoire ci-dessus.

Dans Python 3.7, le chemin absolu est utilisé. Les résultats sont présentés à la fin de cette section.

Obtenir le nom du fichier et le nom du répertoire du fichier en cours d'exécution.

Pour obtenir le nom du fichier et du répertoire du fichier en cours d'exécution, utilisez la fonction suivante dans le module os.path de la bibliothèque standard.

  • os.path.basename()
  • os.path.dirname()
print('basename:    ', os.path.basename(__file__))
print('dirname:     ', os.path.dirname(__file__))

Résultat de l'exécution.

# basename:     file_path.py
# dirname:      data/src

Obtenir le chemin absolu du fichier en cours d'exécution.

Si un chemin relatif est obtenu avec __file__, il peut être converti en chemin absolu avec os.path.abspath(). Les répertoires peuvent également être obtenus comme des chemins absolus.

print('abspath:     ', os.path.abspath(__file__))
print('abs dirname: ', os.path.dirname(os.path.abspath(__file__)))

Résultat de l'exécution.

# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Si un chemin absolu est spécifié dans os.path.abspath(), il sera retourné tel quel. Par conséquent, si __file__ est un chemin absolu, ce qui suit ne provoquera pas d'erreur.

  • os.path.abspath(__file__)

Lit d'autres fichiers en fonction de l'emplacement du fichier en cours d'exécution.

Si vous souhaitez lire d'autres fichiers en fonction de l'emplacement (chemin) du fichier en cours d'exécution, joignez les deux fichiers suivants à l'aide de os.path.join().

  • Répertoire du fichier en cours d'exécution
  • Chemin relatif vers le fichier à lire à partir du fichier en cours d'exécution.

Si vous voulez lire un fichier dans le même répertoire que le fichier que vous exécutez, il suffit de concaténer le nom du fichier.

print('[set target path 1]')
target_path_1 = os.path.join(os.path.dirname(__file__), 'target_1.txt')

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

Résultat de l'exécution.

# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!

Le niveau supérieur est représenté par “. \”. Vous pouvez le laisser tel quel, mais vous pouvez utiliser os.path.normpath() pour normaliser le chemin et supprimer les “. \” et d'autres caractères.

print('[set target path 2]')
target_path_2 = os.path.join(os.path.dirname(__file__), '../dst/target_2.txt')

print('target_path_2: ', target_path_2)
print('normalize    : ', os.path.normpath(target_path_2))

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Résultat de l'exécution.

# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Déplace le répertoire courant vers le répertoire du fichier en cours d'exécution.

Utilisez os.chdir() pour déplacer le répertoire courant vers le répertoire du fichier en cours d'exécution dans le script.

Vous pouvez voir qu'il est déplacé par os.getcwd().

print('[change directory]')
os.chdir(os.path.dirname(os.path.abspath(__file__)))
print('getcwd:      ', os.getcwd())

Résultat de l'exécution.

# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

Une fois que le répertoire courant a été déplacé, il n'est pas nécessaire de le concaténer avec le répertoire du fichier en cours d'exécution lors de la lecture du fichier. Vous pouvez simplement spécifier le chemin relatif au répertoire du fichier en cours d'exécution.

print('[set target path 1 (after chdir)]')
target_path_1 = 'target_1.txt'

print('target_path_1: ', target_path_1)

print('read target file:')
with open(target_path_1) as f:
    print(f.read())

print()
print('[set target path 2 (after chdir)]')
target_path_2 = '../dst/target_2.txt'

print('target_path_2: ', target_path_2)

print('read target file:')
with open(target_path_2) as f:
    print(f.read())

Résultat de l'exécution.

# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Le même traitement peut être effectué quel que soit le répertoire courant au moment de l'exécution.

Comme nous l'avons montré, il est possible de charger des fichiers en fonction de l'emplacement du fichier de script, indépendamment du répertoire courant au moment de l'exécution, en utilisant l'une des méthodes suivantes.

  • Concaténer le répertoire du fichier en cours d'exécution et le chemin relatif vers le fichier à lire à partir du fichier en cours d'exécution en utilisant os.path.join().
  • Déplace le répertoire courant vers le répertoire du fichier en cours d'exécution.

Il est plus facile de déplacer le répertoire courant, mais bien sûr, si vous voulez lire ou écrire d'autres fichiers après cela, vous devez tenir compte du fait que le répertoire courant a été déplacé.

Les résultats des exemples précédents sont résumés ci-dessous.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     data/src/file_path.py
# basename:     file_path.py
# dirname:      data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  data/src/../dst/target_2.txt
# normalize    :  data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Le résultat de la spécification du chemin absolu est le suivant.

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook

python3 /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook
# __file__:     /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# basename:     file_path.py
# dirname:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/../dst/target_2.txt
# normalize    :  /Users/mbp/Documents/my-project/python-snippets/notebook/data/dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!

Le résultat du déplacement du répertoire courant dans le terminal et de l'exécution du même fichier script est présenté ci-dessous. Vous pouvez voir que le même fichier peut être lu même s'il est exécuté à partir d'un emplacement différent.

cd data/src

pwd
# /Users/mbp/Documents/my-project/python-snippets/notebook/data/src

python3 file_path.py
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# __file__:     file_path.py
# basename:     file_path.py
# dirname:      
# abspath:      /Users/mbp/Documents/my-project/python-snippets/notebook/data/src/file_path.py
# abs dirname:  /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2]
# target_path_2:  ../dst/target_2.txt
# normalize    :  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!
# 
# [change directory]
# getcwd:       /Users/mbp/Documents/my-project/python-snippets/notebook/data/src
# 
# [set target path 1 (after chdir)]
# target_path_1:  target_1.txt
# read target file:
# !! This is "target_1.txt" !!
# 
# [set target path 2 (after chdir)]
# target_path_2:  ../dst/target_2.txt
# read target file:
# !! This is "target_2.txt" !!