cosa significa / fa la variabile __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__))

Di solito li fisso solo con il percorso effettivo. Ma c'è una ragione per queste affermazioni che determinano il percorso in fase di esecuzione e vorrei davvero comprendere il modulo os.path in modo da poter iniziare ad usarlo.

Risposte:


163

Quando un modulo viene caricato da un file in Python, __file__viene impostato sul suo percorso. È quindi possibile utilizzarlo con altre funzioni per trovare la directory in cui si trova il file.

Prendendo i tuoi esempi uno alla volta:

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.

Puoi vedere i vari valori restituiti da questi qui:

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__)))

e assicurati di eseguirlo da posizioni diverse (come ./text.py, ~/python/text.pye così via) per vedere quale differenza fa.


7
Buona risposta, ma vedi un altro dettaglio importante da altre risposte: __file__NON è definito in tutti i casi, ad esempio moduli C collegati staticamente. Non possiamo contare sul fatto di __file__essere sempre disponibili.
Chris Johnson,

5
Nell'interprete, ritornano tutti gli esempi name '__file__' is not defined.
user1063287

10
@ user1063287 Guarda la risposta di DemoUser; __file__è il percorso del file da cui è stato caricato il modulo, se è stato caricato da un file. Questo significa che __file__funzionerà solo quando lo esegui come uno script non nell'interprete (a meno che non lo importi in un interprete ...)
GIOVANI

59

Voglio solo prima affrontare un po 'di confusione. __file__non è un carattere jolly, è un attributo. Attributi e metodi di sottolineatura doppia sono considerati "speciali" per convenzione e servono a uno scopo speciale.

http://docs.python.org/reference/datamodel.html mostra molti dei metodi e degli attributi speciali, se non tutti.

In questo caso __file__è un attributo di un modulo (un oggetto modulo). In Python un .pyfile è un modulo. Quindi import amoduleavrà un attributo __file__che significa cose diverse in circostanze diverse.

Tratto dai documenti:

__file__è il percorso del file da cui è stato caricato il modulo, se è stato caricato da un file. L' __file__attributo non è presente per i moduli C che sono staticamente collegati all'interprete; per i moduli di estensione caricati dinamicamente da una libreria condivisa, è il percorso del file della libreria condivisa.

Nel tuo caso il modulo sta accedendo al proprio __file__attributo nello spazio dei nomi globale.

Per vederlo in azione prova:

# file: test.py

print globals()
print __file__

E corri:

python test.py

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

23

Per la documentazione :

__file__è il percorso del file da cui è stato caricato il modulo, se è stato caricato da un file. L' __file__attributo non è presente per i moduli C che sono staticamente collegati all'interprete; per i moduli di estensione caricati dinamicamente da una libreria condivisa, è il percorso del file della libreria condivisa.

e anche :

__file__deve essere il "percorso" del file a meno che il modulo non sia incorporato (e quindi elencato in sys.builtin_module_names) nel qual caso l'attributo non è impostato.


13

L'uso __file__combinato con vari os.pathmoduli consente a tutti i percorsi di essere relativi alla posizione della directory del modulo corrente. Ciò consente ai tuoi moduli / progetti di essere portabili su altre macchine.

Nel tuo progetto fai:

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

e quindi prova a distribuirlo sul tuo server con una directory di distribuzione come /home/web/mydevproject/allora il tuo codice non sarà in grado di trovare correttamente i percorsi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.