¿Qué significa / hace 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__))

Por lo general, solo los conecto con el camino real. Pero hay una razón para estas declaraciones que determinan la ruta en tiempo de ejecución, y realmente me gustaría entender el módulo os.path para que pueda comenzar a usarlo.

descarga
fuente

Respuestas:

163

Cuando un módulo se carga desde un archivo en Python, __file__se establece en su ruta. Luego puede usar eso con otras funciones para encontrar el directorio en el que se encuentra el archivo.

Tomando sus ejemplos uno a la vez:

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.

Puede ver los diversos valores devueltos por estos aquí:

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

y asegúrese de ejecutarlo desde diferentes ubicaciones (como ./text.py, ~/python/text.pyetc.) para ver qué diferencia hace.

paxdiablo
fuente
77
Buena respuesta, pero vea otro detalle importante de otras respuestas: __file__NO está definido en todos los casos, por ejemplo, módulos C estáticamente vinculados. No podemos contar con __file__estar siempre disponibles.
Chris Johnson
55
En intérprete, todos los ejemplos regresan name '__file__' is not defined.
user1063287
10
@ user1063287 Mira la respuesta de DemoUser; __file__es la ruta del archivo desde el que se cargó el módulo, si se cargó desde un archivo. Esto significa __file__que solo funcionará cuando lo ejecute como un script que no esté en el intérprete (a menos que lo importe en el intérprete ...)
JOVEN
59

Solo quiero abordar algo de confusión primero. __file__no es un comodín, es un atributo. Los atributos y métodos de subrayado doble se consideran "especiales" por convención y tienen un propósito especial.

http://docs.python.org/reference/datamodel.html muestra muchos de los métodos y atributos especiales, si no todos.

En este caso __file__es un atributo de un módulo (un objeto de módulo). En Python un .pyarchivo es un módulo. Entonces import amoduletendrá un atributo de lo __file__que significa cosas diferentes en circunstancias diferentes.

Tomado de los documentos:

__file__es la ruta del archivo desde el que se cargó el módulo, si se cargó desde un archivo. El __file__atributo no está presente para los módulos C que están vinculados estáticamente en el intérprete; para módulos de extensión cargados dinámicamente desde una biblioteca compartida, es la ruta del archivo de la biblioteca compartida.

En su caso, el módulo está accediendo a su propio __file__atributo en el espacio de nombres global.

Para ver esto en acción, intente:

# file: test.py

print globals()
print __file__

Y correr:

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
fuente
23

Por la documentación :

__file__es la ruta del archivo desde el que se cargó el módulo, si se cargó desde un archivo. El __file__atributo no está presente para los módulos C que están vinculados estáticamente en el intérprete; para módulos de extensión cargados dinámicamente desde una biblioteca compartida, es la ruta del archivo de la biblioteca compartida.

y también :

__file__debe ser la "ruta" del archivo a menos que el módulo esté integrado (y, por lo tanto, esté incluido en él sys.builtin_module_names), en cuyo caso el atributo no está configurado.

Sudhir Bastakoti
fuente
13

El uso __file__combinado con varios os.pathmódulos permite que todas las rutas sean relativas a la ubicación del directorio del módulo actual. Esto permite que sus módulos / proyectos sean portátiles a otras máquinas.

En tu proyecto haces:

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

e intente implementarlo en su servidor con un directorio de implementaciones como /home/web/mydevproject/su código no podrá encontrar las rutas correctamente.

Sam Dolan
fuente