Esto puede parecer una pregunta para novatos, pero no lo es. Algunos enfoques comunes no funcionan en todos los casos:
sys.argv [0]
Esto significa usar path = os.path.abspath(os.path.dirname(sys.argv[0]))
, pero esto no funciona si está ejecutando desde otro script de Python en otro directorio, y esto puede suceder en la vida real.
__expediente__
Esto significa usar path = os.path.abspath(os.path.dirname(__file__))
, pero descubrí que esto no funciona:
py2exe
no tiene un__file__
atributo, pero hay una solución alternativa- Cuando se ejecuta desde IDLE con
execute()
no hay__file__
atributo - OS X 10.6 donde consigo
NameError: global name '__file__' is not defined
Preguntas relacionadas con respuestas incompletas:
- Python - Buscar ruta al archivo que se está ejecutando
- La ruta al archivo actual depende de cómo ejecuto el programa
- ¿Cómo saber la ruta del script en ejecución en Python?
- Cambiar el directorio al directorio de un script Python
Estoy buscando una solución genérica , una que funcione en todos los casos de uso anteriores.
Actualizar
Aquí está el resultado de un caso de prueba:
Salida de python a.py (en Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
subdir / b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
árbol
C:.
| a.py
\---subdir
b.py
NameError: global name '__file__' is not defined
el uso de archivos y esto no está dentro de IDLE. Piensa que__file__
se define solo dentro de los módulos.__file__
no tuvo nada que ver con Unicode. No se porque__file__
no está definido, pero estoy buscando una solución genérica que funcione en todos los casos.some_path/module_locator.py
?Primero, necesita importar
inspect
yos
A continuación, donde quiera encontrar el archivo fuente, simplemente use
fuente
NameError: global name '__file__' is not defined
(otra solución causó esto).lambda:_
. Funcionó para mí, no estoy seguro de que siempre funcione.lambda:0
probablemente corre más rápido en una cantidad inconmensurablemente pequeña (o tal vez no tan pequeña ... ¿podría ser una carga inmediata o algo aún más rápido para0
una carga global para_
?) Discutible si es más limpio o más fácil de leer o aún más inteligente / oscuro.getsourcefile(lambda:0)
tendrá sentido y solo regresaráNone
si intenta ejecutarlo en un mensaje interactivo (yalambda
que no estará en ningún archivo fuente). Si desea saber de dónde viene otra función u objeto en un entorno interactivo, ¿talabspath(getsourcefile(thatFunctionOrObject))
vez sea más útil para usted?esta solución es robusta incluso en ejecutables
fuente
entry_point: console_script
, pero ninguna de las otras respuestas.Me encontraba con un problema similar, y creo que esto podría resolver el problema:
Funciona para scripts regulares y en inactivo. ¡Todo lo que puedo decir es probarlo para otros!
Mi uso típico:
Ahora uso __modpath__ en lugar de __file__.
fuente
__modpath__
debe cambiarse el nombre. Probablemente tampoco necesite laglobal
declaración. De lo contrario +1!module_path()
. es decirmodule_path(lambda _: None)
, que no dependa de los otros contenidos de la secuencia de comandos que se encuentra.lambda _: None
y la he usado durante los últimos dos años, pero justo ahora descubrí que podía condensarla en sololambda:0
. ¿Hay alguna razón particular por la que sugirió la forma que hizo, con un argumento ignorado_
, en lugar de sin ningún argumento? ¿Hay algo superior sobre elNone
prefijo con un espacio en lugar de solo0
? Ambos son igualmente crípticos, creo, solo uno tiene 8 caracteres de largo mientras que el otro tiene 14 caracteres de largo.lambda _:
es una función que toma un argumento ylambda:
no toma ninguna. No importa ya que la función nunca se llama. Del mismo modo, no importa qué valor de retorno se use. Supongo que elegíNone
porque en ese momento parecía indicar que era mejor una función de no hacer nada y nunca llamarla. El espacio frente a él es opcional y de nuevo solo para mejorar la legibilidad (siempre tratar de seguir PEP8 es adictivo).lambda
embargo, obviamente es un abuso usarlo para algo que nunca debió hacer. Si tuviera que seguir PEP8, creo que el contenido correcto para él seríapass
, noNone
, pero no es válido poner una declaración en alambda
, por lo que debe poner algo con un valor. Hay algunas cosas válidas de 2 caracteres que podría poner, pero creo que las únicas cosas válidas de un solo carácter que puede poner son 0-9 (o un nombre de variable de un solo carácter asignado fuera delambda
.) Creo que la0
mejor indica la nada de 0- 9)La respuesta corta es que no hay una forma garantizada de obtener la información que desea , sin embargo, hay heurísticas que funcionan casi siempre en la práctica. Podrías mirar ¿Cómo encuentro la ubicación del ejecutable en C? . Discute el problema desde un punto de vista C, pero las soluciones propuestas se transcriben fácilmente a Python.
fuente
Consulte mi respuesta a la pregunta Importar módulos de la carpeta principal para obtener información relacionada, incluido por qué mi respuesta no utiliza la
__file__
variable no confiable . Esta solución simple debe ser compatible con diferentes sistemas operativos como los módulosos
yinspect
venir como parte de Python.Primero, debe importar partes de los módulos de inspección y os .
Luego, use la siguiente línea en cualquier otro lugar que sea necesario en su código Python:
Cómo funciona:
Desde el módulo incorporado
os
(descripción a continuación), laabspath
herramienta se importa.Luego
getsourcefile
(la descripción a continuación) se importa desde el módulo incorporadoinspect
.abspath(path)
devuelve la versión absoluta / completa de una ruta de archivogetsourcefile(lambda:0)
de alguna manera obtiene el archivo fuente interno del objeto de función lambda, por lo que devuelve'<pyshell#nn>'
en el shell de Python o devuelve la ruta del archivo del código Python que se está ejecutando actualmente.El uso
abspath
del resultado degetsourcefile(lambda:0)
debe asegurarse de que la ruta del archivo generado sea la ruta completa del archivo Python.Esta solución explicada se basó originalmente en el código de la respuesta en ¿Cómo obtengo la ruta del archivo ejecutado actual en Python? .
fuente
Simplemente has llamado:
en vez de:
abspath()
le proporciona la ruta absoluta desys.argv[0]
(el nombre del archivo en el que se encuentra su código) ydirname()
devuelve la ruta del directorio sin el nombre del archivo.fuente
Esto debería hacer el truco de una manera multiplataforma (siempre que no esté utilizando el intérprete o algo así):
sys.path[0]
es el directorio en el que se encuentra su secuencia de comandos de llamada (el primer lugar donde busca módulos para ser utilizados por esa secuencia de comandos). Podemos quitar el nombre del archivo al final desys.argv[0]
(que es lo que hice conos.path.basename
).os.path.join
simplemente los une de una manera multiplataforma.os.path.realpath
solo nos aseguramos de que si obtenemos enlaces simbólicos con nombres diferentes que el script en sí mismo, sigamos obteniendo el nombre real del script.No tengo una Mac; Por lo tanto, no he probado esto en uno. Avísame si funciona, como parece que debería. Probé esto en Linux (Xubuntu) con Python 3.4. Tenga en cuenta que muchas soluciones para este problema no funcionan en Mac (ya que he oído eso
__file__
no está presente en Mac).Tenga en cuenta que si su script es un enlace simbólico, le dará la ruta del archivo al que se vincula (y no la ruta del enlace simbólico).
fuente
Puedes usar
Path
desde elpathlib
módulo:Puede usar call to
parent
para ir más lejos en el camino:fuente
__file__
variable que puede ser poco confiable (no siempre es la ruta completa del archivo, no funciona en todos los sistemas operativos, etc.) como los usuarios de StackOverflow han mencionado a menudo. Cambiar la respuesta para que no se incluya causará menos problemas y será más compatible con la compatibilidad. Para obtener más información, consulte stackoverflow.com/a/33532002/3787376 .Si el código proviene de un archivo, puede obtener su nombre completo
También puede recuperar el nombre de la función como
f_code.co_name
fuente
Simplemente agregue lo siguiente:
O:
fuente
Mi solución es:
fuente
fuente
'__file__'
no debería ser una cadena, segundo, si lo hiciera__file__
, esto solo funcionaría para el archivo en el que se encuentra esta línea de código, y no para el archivo que se ejecuta.