tutorial lenguaje español descargar python

lenguaje - Python__file__ ¿atributo absoluto o relativo?



python wikipedia (4)

Tengo problemas para entender __file__ . Por lo que entiendo, __file__ devuelve la ruta absoluta desde la que se cargó el módulo.

Estoy teniendo problemas para producir esto: tengo un abc.py con una declaración print __file__ , ejecutando desde /d/projects/ python abc.py devuelve abc.py ejecutando desde /d/ returns projects/abc.py ¿Alguna razón por qué?


Último ejemplo simple:

from os import path, getcwd, chdir def print_my_path(): print(''cwd: {}''.format(getcwd())) print(''__file__:{}''.format(__file__)) print(''abspath: {}''.format(path.abspath(__file__))) print_my_path() chdir(''..'') print_my_path()

En Python-2. *, La segunda llamada determina de forma incorrecta el path.abspath(__file__) basado en el directorio actual:

cwd: C:/codes/py __file__:cwd_mayhem.py abspath: C:/codes/py/cwd_mayhem.py cwd: C:/codes __file__:cwd_mayhem.py abspath: C:/codes/cwd_mayhem.py

Como señaló @techtonik, en Python 3.4+, esto funcionará bien ya que __file__ devuelve una ruta absoluta.


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 en sys.path el resultado es absoluto, pero si está ubicado en una ruta relativa en sys.path el resultado es relativo.

Ahora el archivo de inicio site.py se encarga de entregar solo la ruta absoluta en sys.path , excepto la inicial '''' , por lo que si no la cambia por otros medios que no sea establecer la PYTHONPATH (cuya ruta también se hace absoluta, antes de ponerle un prefijo sys.path ), siempre obtendrá una ruta absoluta, pero cuando se accede al módulo a través del directorio actual.

Ahora, si engañas a sys.path de una manera divertida, puedes obtener cualquier cosa.

Como ejemplo, si tiene un módulo de muestra foo.py en /tmp/ con el código:

import sys print(sys.path) print (__file__)

Si ingresas / tmp obtienes:

>>> import foo ['''', ''/tmp'', ''/usr/lib/python3.3'', ...] ./foo.py

Cuando está en /home/user , si agrega /tmp su PYTHONPATH obtiene:

>>> import foo ['''', ''/tmp'', ''/usr/lib/python3.3'', ...] /tmp/foo.py

Incluso si agrega ../../tmp , se normalizará y el resultado será el mismo.

Pero si en lugar de usar PYTHONPATH utilizas directamente alguna ruta divertida, obtienes un resultado tan divertido como la causa.

>>> import sys >>> sys.path.append(''../../tmp'') >>> import foo ['''', ''/usr/lib/python3.3'', .... , ''../../tmp''] ../../tmp/foo.py

Guido explica en el hilo citado anteriormente, por qué python no intenta transformar todas las entradas en rutas absolutas:

no queremos tener que llamar a getpwd () en cada importación ... getpwd () es relativamente lento y algunas veces puede fallar directamente.

Entonces tu camino se usa tal como es .


De la documentation :

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

Del mail.python.org/pipermail/python-dev/2010-February/097461.html vinculado por @kindall en un comentario a la pregunta:

No he intentado reproducir este ejemplo en particular, pero la razón es que no queremos tener que llamar a getpwd () en cada importación ni queremos tener algún tipo de variable en proceso para almacenar en caché el directorio actual. (getpwd () es relativamente lento y, a veces, puede fallar por completo, y tratar de almacenarlo en caché tiene un cierto riesgo de error.)

Lo que hacemos, en cambio, es un código en site.py que recorre los elementos de sys.path y los convierte en rutas absolutas. Sin embargo, este código se ejecuta antes de que '''' se inserte en el frente de sys.path, de modo que el valor inicial de sys.path sea ''''.

Para el resto de esto, considere sys.path no incluir '''' .

Por lo tanto, si se encuentra fuera de la parte de sys.path que contiene el módulo, obtendrá una ruta absoluta . Si se encuentra dentro de la parte de sys.path que contiene el módulo, obtendrá una ruta relativa .

Si carga un módulo en el directorio actual y el directorio actual no está en sys.path , obtendrá una ruta absoluta.

Si carga un módulo en el directorio actual y el directorio actual está en sys.path , obtendrá una ruta relativa.


__file__ es absoluto desde Python 3.4 , excepto cuando se ejecuta un script directamente usando una ruta relativa:

__file__ atributos del módulo __file__ (y los valores relacionados) ahora deberían contener rutas absolutas de forma predeterminada, con la única excepción de __main__.__file__ cuando un script se ha ejecutado directamente usando una ruta relativa. (Contribuido por Brett Cannon en bpo-18416 ).

Sin embargo, no estoy seguro de si resuelve los enlaces simbólicos.

Ejemplo de pasar una ruta relativa:

$ python script.py