que signifie / fait la variable __file__?

178
A = os.path.join(os.path.dirname(__file__), '..')

B = os.path.dirname(os.path.realpath(__file__))

C = os.path.abspath(os.path.dirname(__file__))

Je les connecte généralement simplement avec le chemin réel. Mais il y a une raison pour ces déclarations qui déterminent le chemin au moment de l'exécution, et j'aimerais vraiment comprendre le module os.path afin que je puisse commencer à l'utiliser.

abattement
la source

Réponses:

163

Lorsqu'un module est chargé à partir d'un fichier en Python, il __file__est défini sur son chemin. Vous pouvez ensuite l'utiliser avec d'autres fonctions pour trouver le répertoire dans lequel se trouve le fichier.

Prenons vos exemples un par un:

A = os.path.join(os.path.dirname(__file__), '..')
# A is the parent directory of the directory where program resides.

B = os.path.dirname(os.path.realpath(__file__))
# B is the canonicalised (?) directory where the program resides.

C = os.path.abspath(os.path.dirname(__file__))
# C is the absolute path of the directory where the program resides.

Vous pouvez voir les différentes valeurs renvoyées ici:

import os
print(__file__)
print(os.path.join(os.path.dirname(__file__), '..'))
print(os.path.dirname(os.path.realpath(__file__)))
print(os.path.abspath(os.path.dirname(__file__)))

et assurez-vous de l'exécuter à partir d'emplacements différents (tels que ./text.py, ~/python/text.pyetc.) pour voir quelle différence cela fait.

paxdiablo
la source
7
Bonne réponse, mais voir autre un détail important des autres réponses: __file__n'est PAS défini dans tous les cas, par exemple les modules C liés statiquement. Nous ne pouvons pas compter sur __file__une disponibilité permanente.
Chris Johnson
5
Dans l'interpréteur, tous les exemples retournent name '__file__' is not defined.
user1063287
10
@ user1063287 Regardez la réponse de DemoUser; __file__est le chemin du fichier à partir duquel le module a été chargé, s'il a été chargé à partir d'un fichier. Cela signifie __file__ne fonctionnera que lorsque vous l'exécuterez en tant que script pas dans l'interpréteur. (Sauf si vous l'importez dans l'interpréteur ...)
JEUNE
59

Je veux juste aborder une certaine confusion en premier. __file__n'est pas un joker, c'est un attribut. Les attributs et méthodes de double soulignement sont considérés comme "spéciaux" par convention et ont un objectif particulier.

http://docs.python.org/reference/datamodel.html montre la plupart des méthodes et attributs spéciaux, sinon tous.

Dans ce cas, il __file__s'agit d'un attribut d'un module (un objet module). En Python, un .pyfichier est un module. Ainsi import amoduleaura un attribut __file__qui signifie différentes choses dans des circonstances différentes.

Tiré de la documentation:

__file__est le chemin du fichier à partir duquel le module a été chargé, s'il a été chargé à partir d'un fichier. L' __file__attribut n'est pas présent pour les modules C qui sont liés statiquement dans l'interpréteur; pour les modules d'extension chargés dynamiquement à partir d'une bibliothèque partagée, c'est le chemin du fichier de bibliothèque partagée.

Dans votre cas, le module accède à son propre __file__attribut dans l'espace de noms global.

Pour voir cela en action, essayez:

# file: test.py

print globals()
print __file__

Et courir:

python test.py

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
 'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py
Derek Litz
la source
23

Selon la documentation :

__file__est le chemin du fichier à partir duquel le module a été chargé, s'il a été chargé à partir d'un fichier. L' __file__attribut n'est pas présent pour les modules C qui sont liés statiquement dans l'interpréteur; pour les modules d'extension chargés dynamiquement à partir d'une bibliothèque partagée, c'est le chemin du fichier de bibliothèque partagée.

et aussi :

__file__doit être le «chemin» du fichier à moins que le module ne soit intégré (et donc répertorié dans sys.builtin_module_names) auquel cas l'attribut n'est pas défini.

Sudhir Bastakoti
la source
13

L'utilisation __file__combinée avec divers os.pathmodules permet à tous les chemins d'être relatifs à l'emplacement du répertoire actuel du module. Cela permet à vos modules / projets d'être portables vers d'autres machines.

Dans votre projet, vous faites:

A = '/Users/myname/Projects/mydevproject/somefile.txt'

puis essayez de le déployer sur votre serveur avec un répertoire de déploiements comme /home/web/mydevproject/alors votre code ne pourra pas trouver les chemins correctement.

Sam Dolan
la source