filename - ¿Cómo obtengo la ruta del archivo ejecutado actual en Python?
python os path filename (10)
Consulte mi respuesta a la pregunta Importar módulos de la carpeta principal para obtener información relacionada, incluido el motivo por el cual mi respuesta no utiliza la variable __file__
poco __file__
. Esta solución simple debe ser compatible cruzada con diferentes sistemas operativos, ya que los módulos os
e inspect
vienen como parte de Python.
En primer lugar, debe importar partes de los módulos de inspección y os .
from inspect import getsourcefile
from os.path import abspath
A continuación, use la siguiente línea en cualquier otro lugar que sea necesario en su código de Python:
abspath(getsourcefile(lambda:0))
Cómo funciona:
A partir del módulo incorporado abspath
(descripción a continuación), se abspath
herramienta abspath
.
Rutinas del sistema operativo para Mac, NT o Posix, según el sistema en el que trabajemos.
A continuación, el getsourcefile
(descripción a continuación) se importa desde el módulo integrado inspect
.
Obtenga información útil de objetos en vivo de Python.
-
abspath(path)
devuelve la versión absoluta / completa de una ruta de archivo -
getsourcefile(lambda:0)
alguna manera obtiene el archivo fuente interno del objeto función lambda, por lo que devuelve''<pyshell#nn>''
en el shell Python o devuelve la ruta del archivo del código Python que se está ejecutando actualmente.
El uso de abspath
en el resultado de getsourcefile(lambda:0)
debe garantizar que la ruta del archivo generada sea la ruta completa del archivo de 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? .
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 otra secuencia de comandos de Python en otro directorio, y esto puede suceder en la vida real. .
__archivo__
Esto significa usar path = os.path.abspath(os.path.dirname(__file__))
, pero descubrí que esto no funciona:
-
py2exe
no tiene un atributo__file__
, pero hay una workaround - Cuando ejecuta desde IDLE con
execute()
no hay ningún atributo__file__
- OS X 10.6 donde obtengo
NameError: global name ''__file__'' is not defined
Preguntas relacionadas con respuestas incompletas:
- Python - Encuentra la ruta al archivo que se ejecuta
- 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 una secuencia de comandos de Python
Estoy buscando una solución genérica , que funcione en todos los casos de uso anteriores.
Actualizar
Aquí está el resultado de un testcase:
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
En primer lugar, debe importar de inspect
y os
from inspect import getsourcefile
from os.path import abspath
A continuación, donde sea que desee encontrar el archivo fuente, solo use
abspath(getsourcefile(lambda:0))
Esto debería funcionar de forma multiplataforma (siempre que no uses el intérprete o algo así):
import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))
sys.path[0]
es el directorio en el que se encuentra el script de llamada (en primer lugar, busca los módulos que usará ese script). Podemos tomar el nombre del archivo por sí mismo al final de sys.argv[0]
(que es lo que hice con os.path.basename
). os.path.join
simplemente los une en una plataforma cruzada. os.path.realpath
simplemente se asegura de que si obtenemos enlaces simbólicos con nombres diferentes a los del script en sí, sigamos obteniendo el nombre real del script.
No tengo una Mac; entonces, no he probado esto en uno. Por favor, avíseme 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 que __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).
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 en Python.
Me encontré con un problema similar, y creo que esto podría resolver el problema:
def module_path(local_function):
'''''' returns the module path without the use of __file__. Requires a function defined
locally in the module.
from http://.com/questions/729583/getting-file-path-of-imported-module''''''
return os.path.abspath(inspect.getsourcefile(local_function))
Funciona para scripts regulares y en inactivo. ¡Todo lo que puedo decir es probarlo para los demás!
Mi uso típico:
from toolbox import module_path
def main():
pass # Do stuff
global __modpath__
__modpath__ = module_path(main)
Ahora uso __modpath__ en lugar de __file__.
No puede determinar directamente la ubicación del script principal que se está ejecutando. Después de todo, a veces el script no provenía de ningún archivo. Por ejemplo, podría provenir del intérprete interactivo o código generado dinámicamente almacenado solo en la memoria.
Sin embargo, puede determinar de manera confiable la ubicación de un módulo, ya que los módulos siempre se cargan desde un archivo. Si crea un módulo con el siguiente código y lo coloca en el mismo directorio que su script principal, entonces el script principal puede importar el módulo y usarlo para ubicarse.
some_path / module_locator.py:
def we_are_frozen():
# All of the modules are built-in to the interpreter, e.g., by py2exe
return hasattr(sys, "frozen")
def module_path():
encoding = sys.getfilesystemencoding()
if we_are_frozen():
return os.path.dirname(unicode(sys.executable, encoding))
return os.path.dirname(unicode(__file__, encoding))
some_path / main.py:
import module_locator
my_path = module_locator.module_path()
Si tiene varias secuencias de comandos principales en directorios diferentes, es posible que necesite más de una copia de module_locator.
Por supuesto, si su script principal es cargado por alguna otra herramienta que no le permite importar módulos que comparten el mismo script, entonces no tiene suerte. En casos como ese, la información que está buscando simplemente no existe en ningún lugar de su programa. Su mejor opción sería presentar un error con los autores de la herramienta.
Puede usar Path
desde el módulo pathlib
:
from pathlib import Path
# ...
Path(__file__)
Puede usar la llamada al parent
para ir más allá en la ruta:
Path(__file__).parent
Simplemente agregue lo siguiente:
from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)
O:
from sys import *
print(sys.argv[0])
Simplemente has llamado:
path = os.path.abspath(os.path.dirname(sys.argv[0]))
en lugar de:
path = os.path.dirname(os.path.abspath(sys.argv[0]))
abspath()
le proporciona la ruta absoluta de sys.argv[0]
(el nombre de archivo en el que se encuentra su código) y dirname()
devuelve la ruta del directorio sin el nombre del archivo.
esta solución es robusta incluso en ejecutables
import inspect, os.path
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))