Tengo scripts que llaman a otros archivos de script pero necesito obtener la ruta del archivo que se está ejecutando actualmente en el proceso.
Por ejemplo, digamos que tengo tres archivos. Usando execfile :
script_1.py
llamadasscript_2.py
.- A su vez,
script_2.py
llamadasscript_3.py
.
¿Cómo puedo obtener el nombre y la ruta del archivo script_3.py
, desde el código internoscript_3.py
, sin tener que pasar esa información como argumentos script_2.py
?
(La ejecución os.getcwd()
devuelve la ruta de archivo del script inicial original, no la del archivo actual).
__file__
absoluto o relativo?Respuestas:
p1.py:
p2.py:
fuente
inspect.getabsfile()
y funcionó para todos los casos que he probado.os.path.realpath(__file__)
como han dicho otros. También puede usar os.path.realpath para eliminar enlaces simbólicos:
fuente
__file__
devuelve 'script_name.py', y otras veces 'script_name.pyc'. Entonces la salida no es estable."__file__"
entre comillas (como cadena) se obtiene el directorio desde el que se ejecuta cmd, pero__file__
(sin comillas se obtiene la ruta al archivo de origen ... por qué es esoos.path.realpath
función supone que es ladir
parte de la ruta.os.path.dirname(os.path.realpath(__file__))
devuelve el directorio con el archivoos.path.dirname(os.path.realpath("__file__"))
devuelve cwd.os.path.dirname(os.path.realpath("here_be_dragons"))
También devuelve cwd.Actualización 2018-11-28:
Aquí hay un resumen de los experimentos con Python 2 y 3. Con
main.py: ejecuta foo.py
foo.py: ejecuta lib / bar.py
lib / bar.py: imprime expresiones de ruta de archivo
Para Python 2, puede ser más claro cambiar a paquetes para poder usarlos
from lib import bar
, simplemente agregue__init__.py
archivos vacíos a las dos carpetas.Para Python 3,
execfile
no existe; la alternativa más cercana esexec(open(<filename>).read())
, aunque esto afecta los marcos de la pila. Es más fácil de usarimport foo
yimport lib.bar
no se__init__.py
necesitan archivos.Consulte también Diferencia entre importación y archivo de ejecución
Respuesta original
Aquí hay un experimento basado en las respuestas de este hilo, con Python 2.7.10 en Windows.
Los basados en la pila son los únicos que parecen dar resultados confiables. Los dos últimos tienen la sintaxis más corta , es decir:
¡Aquí se agrega a sys como funciones! Crédito a @Usagi y @pablog
Basado en los siguientes tres archivos, y ejecutando main.py desde su carpeta con
python main.py
(también probé archivos ejecutables con rutas absolutas y llamadas desde una carpeta separada).C: \ filepaths \ main.py:
execfile('foo.py')
C: \ filepaths \ foo.py:
execfile('lib/bar.py')
C: \ filepaths \ lib \ bar.py:
fuente
Creo que esto es más limpio:
y obtiene la misma información que:
Donde [0] es el marco actual en la pila (parte superior de la pila) y [1] es para el nombre del archivo, aumente para ir hacia atrás en la pila, es decir
sería el nombre del archivo del script que llamó al marco actual. Además, el uso de [-1] lo llevará al final de la pila, el script de llamada original.
fuente
inspect.getfile()
devuelve el__file__
atributo si se pasa un objeto de módulo.inspect.currentframe()
devuelve el módulo Ergo, esta es una forma costosa de decir__file__
.inspect.stack()
es una función bastante costosa, más que simplementeinspect.currentframe()
, y también llamainspect.getfile()
a un objeto de módulo.fuente
__file__
.os.path.dirname
le dará la ruta relativa desde donde está ejecutando el script. por ejemplo, enpython ../../test.py
laos.path.dirname
voluntad../../
y no en la ruta absoluta al guión. Estaba buscando abspath pero eliminaba el nombre del script. El primer elemento de sys.path aparentemente es la respuestasys.path[0]
.Las sugerencias marcadas como mejores son todas verdaderas si su secuencia de comandos consta de un solo archivo.
Si desea averiguar el nombre del ejecutable (es decir, el archivo raíz pasado al intérprete de Python para el programa actual) desde un archivo que puede importarse como un módulo, debe hacerlo (supongamos que está en un archivo llamado foo.py ):
import inspect
print inspect.stack()[-1][1]
Porque lo último (
[-1]
) en la pila es lo primero que entró (las pilas son estructuras de datos LIFO / FILO).Luego, en el archivo bar.py, si
import foo
imprime bar.py , en lugar de foo.py , que sería el valor de todos estos:__file__
inspect.getfile(inspect.currentframe())
inspect.stack()[0][1]
fuente
sys.modules['__main__'].__file__
, de verdad.esto solo nos dará el nombre del archivo. es decir, si abspath del archivo es c: \ abcd \ abc.py, la segunda línea imprimirá abc.py
fuente
No está del todo claro qué quiere decir con "la ruta del archivo que se está ejecutando actualmente en el proceso".
sys.argv[0]
generalmente contiene la ubicación del script invocado por el intérprete de Python. Consulte la documentación del sistema para obtener más detalles.Como han señalado @Tim y @Pat Notz, el atributo __file__ proporciona acceso a
fuente
Tengo un script que debe funcionar en un entorno Windows. Este código cortado es con lo que he terminado:
Es una decisión bastante hacky. Pero no requiere bibliotecas externas y es lo más importante en mi caso.
fuente
Prueba esto,
fuente
No es necesario inspeccionar ni ninguna otra biblioteca.
Esto funcionó para mí cuando tuve que importar un script (desde un directorio diferente al script ejecutado), que utilizaba un archivo de configuración que residía en la misma carpeta que el script importado.
fuente
los
__file__
atributo funciona tanto para el archivo que contiene el código de ejecución principal como para los módulos importados.Ver https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
fuente
esto imprimiría la ruta del script que se está ejecutando actualmente
fuente
Creo que
__file__
suena como si también quisieras revisar el módulo de inspección .fuente
Puedes usar
inspect.stack()
fuente
Dado que Python 3 es bastante convencional, quería incluir una
pathlib
respuesta, ya que creo que probablemente ahora sea una mejor herramienta para acceder a la información de archivos y rutas.Si está buscando el directorio del archivo actual, es tan fácil como agregar
.parent
a laPath()
declaración:fuente
fuente
Esto debería funcionar:
fuente
fuente
Para obtener el directorio del script de ejecución
fuente
Siempre he usado la función os del directorio de trabajo actual, o CWD. Esto es parte de la biblioteca estándar y es muy fácil de implementar. Aquí hay un ejemplo:
fuente
python script.py
comando en la misma carpeta que ya está, cuando en realidad es lo mismo que ejecutarpwd
en Linux.Utilicé el enfoque con __file__
os.path.abspath(__file__)
pero hay un pequeño truco, devuelve el archivo .py cuando se ejecuta el código la primera vez, las siguientes ejecuciones dan el nombre del archivo * .pyc,
así que me quedé con:
inspect.getfile(inspect.currentframe())
o
sys._getframe().f_code.co_filename
fuente
Escribí una función que tiene en cuenta el eclipse depurador y unittest . Devuelve la carpeta del primer script que ejecutas. Opcionalmente, puede especificar el __file__ var, pero lo principal es que no tiene que compartir esta variable en toda su jerarquía de llamadas .
Tal vez pueda manejar otros casos particulares que no vi, pero para mí está bien.
fuente
Para mantener la coherencia de la migración entre plataformas (macOS / Windows / Linux), intente:
path = r'%s' % os.getcwd().replace('\\','/')
fuente
La forma más simple es:
en script_1.py:
en script_2.py:
PD: Lo he intentado
execfile
, pero dado que lee script_2.py como una cadena,sys.argv[0]
regresó<string>
.fuente
Esto es lo que uso para poder lanzar mi código en cualquier lugar sin problemas.
__name__
siempre se define, pero__file__
solo se define cuando el código se ejecuta como un archivo (por ejemplo, no en IDLE / iPython).Alternativamente, esto se puede escribir como:
fuente
La mayoría de estas respuestas fueron escritas en Python versión 2.xo anterior. En Python 3.x, la sintaxis de la función de impresión ha cambiado para requerir paréntesis, es decir, print ().
Entonces, esta respuesta de puntaje anterior del usuario 13993 en Python 2.x:
Se convierte en Python 3.x:
fuente
si solo quieres el nombre del archivo
./
o.py
puedes probar estofile_name
imprimirá el script de prueba que puede generar lo que quiera cambiando el índice dentro de []fuente
fuente