Me cuesta entender __file__
. Por lo que tengo entendido, __file__
devuelve la ruta absoluta desde la que se cargó el módulo.
Tengo problemas para producir esto: tengo abc.py
una declaración con una print __file__
, que se ejecuta desde /d/projects/
python abc.py
devoluciones abc.py
. corriendo de /d/
devoluciones projects/abc.py
. ¿Alguna razón por la que?
Respuestas:
De la documentación :
Desde el hilo de la lista de correo vinculado por @kindall en un comentario a la pregunta:
Para el resto de esto, considere
sys.path
no incluir''
.Entonces, si está fuera de la parte
sys.path
que contiene el módulo, obtendrá una ruta absoluta . Si está dentro de la partesys.path
que contiene el módulo, obtendrá una ruta relativa .Si se carga un módulo en el directorio actual, y el directorio actual no es en
sys.path
, obtendrá una ruta absoluta.Si carga un módulo en el directorio actual y el directorio actual está dentro
sys.path
, obtendrá una ruta relativa.fuente
sys.path
, obtendrá una ruta absoluta. Si carga un módulo en el directorio actual y el directorio actual está dentrosys.path
, obtendrá una ruta relativa.sys.path
no incluye''
.__file__
es absoluto desde Python 3.4 , excepto cuando se ejecuta un script directamente usando una ruta relativa:Sin embargo, no estoy seguro de si resuelve los enlaces simbólicos.
Ejemplo de pasar una ruta relativa:
fuente
Python 3.4.0 (default, Apr 11 2014, 13:05:11) [GCC 4.8.2] on linux
). Y los enlaces simbólicos no se resuelven en mis pruebas.os.path.realpath(__file__)
la forma correcta de resolver enlaces simbólicos?Ejemplo simple tardío:
En Python-2. *, La segunda llamada determina incorrectamente el
path.abspath(__file__)
basado en el directorio actual:Como señaló @techtonik, en Python 3.4+, esto funcionará bien ya que
__file__
devuelve una ruta absoluta.fuente
__main__
módulo, donde__file__
puede haber una ruta relativa.Con la ayuda del correo de Guido proporcionado por @kindall, podemos entender el proceso de importación estándar como tratar de encontrar el módulo en cada miembro de
sys.path
y el archivo como resultado de esta búsqueda (más detalles en PyMOTW Modules and Imports .). Entonces, si el módulo está ubicado en una ruta absoluta,sys.path
el resultado es absoluto, pero si está ubicado en una ruta relativa,sys.path
el resultado es relativo.Ahora el
site.py
archivo de inicio se encarga de entregar solo la ruta absolutasys.path
, excepto la inicial''
, por lo que si no lo cambia por otros medios que no sean la configuración de PYTHONPATH (cuya ruta también se hace absoluta, antes de prefijarsys.path
), obtendrá siempre un valor absoluto ruta, pero cuando se accede al módulo a través del directorio actual.Ahora, si engaña a sys.path de una manera divertida, puede obtener cualquier cosa.
Como ejemplo, si tiene un módulo de muestra
foo.py
en/tmp/
el código:Si entra / tmp obtiene:
Cuando
/home/user
estás adentro , si agregas/tmp
tuPYTHONPATH
obtienes:Incluso si agrega
../../tmp
, se normalizará y el resultado será el mismo.Pero si en lugar de usar
PYTHONPATH
usas directamente algún camino divertido obtienes un resultado tan divertido como la causa.Guido explica en el hilo citado anteriormente, por qué Python no intenta transformar todas las entradas en rutas absolutas:
Entonces tu camino se usa como está .
fuente