Puede usar __file__para obtener el nombre del archivo actual. Cuando se usa en el módulo principal, este es el nombre del script que se invocó originalmente.
Si desea omitir la parte del directorio (que podría estar presente), puede usar os.path.basename(__file__).
Python 3.2: " Exception NameError: NameError("global name '__file__' is not defined",)"
sdaau
20
@sdaau: __file__no está definido en el intérprete interactivo, porque no tiene sentido allí. Lo establece la implementación de importación, por lo que si usa un mecanismo de importación no estándar, también podría estar desarmado.
Sven Marnach
8
Al menos para Python 2.7, creo que import oses necesario para que esto funcione. Añadiría esto a la respuesta.
Nick Chammas
14
@ cdunn2001: import osy import os.pathson completamente equivalentes.
Sven Marnach
2
@ sven-marnach: Oh, tienes razón . ¡Lo he estado haciendo mal durante años!
cdunn2001
136
import sys
print sys.argv[0]
Esto imprimirá foo.pypara python foo.py, dir/foo.pypara python dir/foo.py, etc. Es el primer argumento para python. (Tenga en cuenta que después de py2exe sería foo.exe).
@DenisMalinovsky: defina "no funcionará". Si llama python linkfile.py, donde linkfile.pyes un enlace simbólico realfile.py, sys.argv[0]será 'linkfile.py', lo que puede o no ser lo que desea; Ciertamente es lo que espero . __file__es lo mismo: lo será linkfile.py. Si desea buscar 'realfile.py'desde 'linkfile.py', intente os.path.realpath('linkfile.py').
Chris Morgan
66
+1 porque es (a) un poco más ordenado y (b) seguirá funcionando en el módulo (donde la variable del archivo sería el archivo del módulo, no el ejecutado).
robert
Esta respuesta es buena porque también funciona en IDLE. Como nota, para obtener solo el nombre del archivo, puede escribir os.path.basename (sys.argv [0])
Steven Bluen
Más importante aún, esto no funciona excepto desde el interior del archivo principal. No use esto, use __file__en su lugar.
Apollys apoya a Monica el
¡¡¡QUÉ!!! ¿Intentaste esto? Exactamente lo contrario es cierto. El interlocutor solicitó el nombre del script de Python que se está ejecutando, no el archivo de Python que se está ejecutando actualmente. Imagine que tiene un script que, cuando ocurre un error, imprime el nombre del script junto con los argumentos permitidos. Pones eso en una función, usando una de estas 2 técnicas. En algún momento, decide mover la función a una biblioteca externa. ¿Desea imprimir el nombre del script principal en ejecución o el nombre del archivo de biblioteca que se está ejecutando?
John Deighan
71
Para completar, pensé que valdría la pena resumir los diversos resultados posibles y proporcionar referencias para el comportamiento exacto de cada uno:
__file__es el archivo actualmente en ejecución, como se detalla en la documentación oficial :
__file__es la ruta del archivo desde el que se cargó el módulo, si se cargó desde un archivo. El __file__atributo puede faltar para ciertos tipos de módulos, como C módulos que están vinculados estáticamente al intérprete; para módulos de extensión cargados dinámicamente desde una biblioteca compartida, es la ruta del archivo de la biblioteca compartida.
Desde Python3.4 en adelante, por número 18416 , __file__siempre es una ruta absoluta, a menos que el archivo actualmente en ejecución sea un script que se haya ejecutado directamente (no a través del intérprete con el-m opción de línea de comando) usando una ruta relativa.
__main__.__file__(requiere importación __main__) simplemente accede al __file__atributo mencionado anteriormente del módulo principal , por ejemplo, del script que se invocó desde la línea de comandos.
sys.argv[0](requiere importación sys) es el nombre del script que se invocó desde la línea de comando, y podría ser una ruta absoluta, como se detalla en la documentación oficial :
argv[0]es el nombre del script (depende del sistema operativo si se trata de un nombre de ruta completo o no). Si el comando se ejecutó utilizando la -copción de línea de comando para el intérprete, argv[0]se establece en la cadena '-c'. Si no se pasó ningún nombre de script al intérprete de Python, argv[0]es la cadena vacía.
Como se mencionó en otra respuesta a esta pregunta , los scripts de Python que se convirtieron en programas ejecutables independientes a través de herramientas como py2exe o PyInstaller podrían no mostrar el resultado deseado al usar este enfoque (es decir sys.argv[0], contendrían el nombre del ejecutable en lugar del nombre de la Python principal archivo dentro de ese ejecutable).
Si ninguna de las opciones mencionadas parece funcionar, probablemente debido a una operación de importación irregular, el módulo de inspección podría resultar útil. En particular, invocar inspect.getfile(...)a inspect.currentframe()podría funcionar, aunque este último volveríaNone cuando se ejecute en una implementación sin marco de pila de Python .
Manejo de enlaces simbólicos
Si el script actual es un enlace simbólico, todo lo anterior devolvería la ruta del enlace simbólico en lugar de la ruta del archivo real y os.path.realpath(...)debería invocarse para extraer este último.
Manipulaciones adicionales que extraen el nombre real del archivo
os.path.basename(...)se puede invocar en cualquiera de los anteriores para extraer el nombre real del archivo y os.path.splitext(...)se puede invocar en el nombre real del archivo para truncar su sufijo, como en os.path.splitext(os.path.basename(...)).
Tenga en cuenta que __file__le dará al archivo donde reside este código, que puede importarse y ser diferente del archivo principal que se está interpretando. Para obtener el archivo principal, se puede usar el módulo especial __main__ :
import __main__ as main
print(main.__file__)
Tenga __main__.__file__en cuenta que funciona en Python 2.7 pero no en 3.2, por lo tanto, use la sintaxis import-as como arriba para hacerlo portátil.
Esto funciona en muchos casos, pero no cuando estoy usando el rPythonpaquete desde el Ridioma. Ese debe ser un caso excepcional que es demasiado difícil de manejar.
Leonid
De hecho, el paquete rPython incorpora el intérprete de python, lo que significa que no hay un archivo 'principal' como el que existe cuando python se ejecuta por sí solo (encontrará el mismo comportamiento cada vez que se incruste python). Importa __main__internamente, para usar al pasar variables entre Ry python, por lo que sería relativamente fácil configurarlo __main__.__file__antes de llamar a cualquier otra cosa, pero ni siquiera estoy seguro de cuál sería un valor apropiado en este caso.
Perkins
42
Las respuestas anteriores son buenas. Pero este método me pareció más eficiente utilizando los resultados anteriores.
Esto da como resultado que el nombre real del archivo de script no es una ruta.
import sys
import os
file_name = os.path.basename(sys.argv[0])
También me gusta dividir la extensión, así que uso: os.path.splitext (os.path.basename (sys.argv [0])) [0]
RufusVS
19
Para las versiones modernas de Python (3.4+), Path(__file__).namedebería ser más idiomático. Además, Path(__file__).stemle da el nombre del script sin la .pyextensión.
todas esas respuestas son geniales, pero tienen algunos problemas Es posible que no veas a primera vista.
definamos lo que queremos: queremos el nombre del script que se ejecutó, no el nombre del módulo actual, por __file__lo que solo funcionará si se usa en el script ejecutado, no en un módulo importado.
sys.argvtambién es cuestionable: ¿qué pasa si su programa fue llamado por pytest? o corredor pydoc? o si fue llamado por uwsgi?
y - hay un tercer método para obtener el nombre del script, no lo he visto en las respuestas - Puedes inspeccionar la pila.
Otro problema es que usted (o algún otro programa) puede manipular sys.argvy__main__.__file__ puede estar presente, puede que no. Puede ser válido o no. ¡Al menos puedes comprobar si el script (el resultado deseado) existe!
mi biblioteca bitranox / lib_programname en github hace exactamente eso:
verificar si __main__está presente
verificar si __main__.__file__está presente
da __main__.__file__un resultado válido (¿existe ese script?)
si no: compruebe sys.argv:
¿hay pytest, docrunner, etc. en sys.argv? -> si es así, ignora eso
¿Podemos obtener un resultado válido aquí?
si no: inspeccione la pila y obtenga el resultado de allí posiblemente
si también la pila no da un resultado válido, entonces lanza una Excepción.
por ese camino, mi solución está trabajando hasta ahora con setup.py test, uwsgi, pytest, pycharm pytest, pycharm docrunner (doctest), dreampie,eclipse
también hay un buen artículo de blog sobre ese problema de Dough Hellman, "Determinando el nombre de un proceso desde Python"
Exception NameError: NameError("global name '__file__' is not defined",)
"__file__
no está definido en el intérprete interactivo, porque no tiene sentido allí. Lo establece la implementación de importación, por lo que si usa un mecanismo de importación no estándar, también podría estar desarmado.import os
es necesario para que esto funcione. Añadiría esto a la respuesta.import os
yimport os.path
son completamente equivalentes.Esto imprimirá
foo.py
parapython foo.py
,dir/foo.py
parapython dir/foo.py
, etc. Es el primer argumento parapython
. (Tenga en cuenta que después de py2exe seríafoo.exe
).fuente
python linkfile.py
, dondelinkfile.py
es un enlace simbólicorealfile.py
,sys.argv[0]
será'linkfile.py'
, lo que puede o no ser lo que desea; Ciertamente es lo que espero .__file__
es lo mismo: lo serálinkfile.py
. Si desea buscar'realfile.py'
desde'linkfile.py'
, intenteos.path.realpath('linkfile.py')
.__file__
en su lugar.Para completar, pensé que valdría la pena resumir los diversos resultados posibles y proporcionar referencias para el comportamiento exacto de cada uno:
__file__
es el archivo actualmente en ejecución, como se detalla en la documentación oficial :Desde Python3.4 en adelante, por número 18416 ,
__file__
siempre es una ruta absoluta, a menos que el archivo actualmente en ejecución sea un script que se haya ejecutado directamente (no a través del intérprete con el-m
opción de línea de comando) usando una ruta relativa.__main__.__file__
(requiere importación__main__
) simplemente accede al__file__
atributo mencionado anteriormente del módulo principal , por ejemplo, del script que se invocó desde la línea de comandos.sys.argv[0]
(requiere importaciónsys
) es el nombre del script que se invocó desde la línea de comando, y podría ser una ruta absoluta, como se detalla en la documentación oficial :Como se mencionó en otra respuesta a esta pregunta , los scripts de Python que se convirtieron en programas ejecutables independientes a través de herramientas como py2exe o PyInstaller podrían no mostrar el resultado deseado al usar este enfoque (es decir
sys.argv[0]
, contendrían el nombre del ejecutable en lugar del nombre de la Python principal archivo dentro de ese ejecutable).Si ninguna de las opciones mencionadas parece funcionar, probablemente debido a una operación de importación irregular, el módulo de inspección podría resultar útil. En particular, invocar
inspect.getfile(...)
ainspect.currentframe()
podría funcionar, aunque este último volveríaNone
cuando se ejecute en una implementación sin marco de pila de Python .Manejo de enlaces simbólicos
Si el script actual es un enlace simbólico, todo lo anterior devolvería la ruta del enlace simbólico en lugar de la ruta del archivo real y
os.path.realpath(...)
debería invocarse para extraer este último.Manipulaciones adicionales que extraen el nombre real del archivo
os.path.basename(...)
se puede invocar en cualquiera de los anteriores para extraer el nombre real del archivo yos.path.splitext(...)
se puede invocar en el nombre real del archivo para truncar su sufijo, como enos.path.splitext(os.path.basename(...))
.Desde Python 3.4 en adelante, según PEP 428 , la
PurePath
clase delpathlib
módulo también se puede usar en cualquiera de los anteriores. Específicamente,pathlib.PurePath(...).name
extrae el nombre real del archivo ypathlib.PurePath(...).stem
extrae el nombre real del archivo sin su sufijo.fuente
Tenga en cuenta que
__file__
le dará al archivo donde reside este código, que puede importarse y ser diferente del archivo principal que se está interpretando. Para obtener el archivo principal, se puede usar el módulo especial __main__ :Tenga
__main__.__file__
en cuenta que funciona en Python 2.7 pero no en 3.2, por lo tanto, use la sintaxis import-as como arriba para hacerlo portátil.fuente
rPython
paquete desde elR
idioma. Ese debe ser un caso excepcional que es demasiado difícil de manejar.__main__
internamente, para usar al pasar variables entreR
ypython
, por lo que sería relativamente fácil configurarlo__main__.__file__
antes de llamar a cualquier otra cosa, pero ni siquiera estoy seguro de cuál sería un valor apropiado en este caso.Las respuestas anteriores son buenas. Pero este método me pareció más eficiente utilizando los resultados anteriores.
Esto da como resultado que el nombre real del archivo de script no es una ruta.
fuente
Para las versiones modernas de Python (3.4+),
Path(__file__).name
debería ser más idiomático. Además,Path(__file__).stem
le da el nombre del script sin la.py
extensión.fuente
from pathlib import Path
primero.pathlib
se introdujo en Python 3.4, por lo que debería funcionar a partir de Python 3.4.Prueba esto:
fuente
Nota: Si está usando Python 3+, entonces debería usar la función print () en su lugar
Suponiendo que el nombre del archivo es
foo.py
, el fragmento a continuacióno
En cuanto a otras extensiones con más caracteres, por ejemplo, el nombre del archivo
foo.pypy
Si quieres extraer de una ruta absoluta
saldrá
foo
fuente
__file__
ysys.argv[0]
, consulte stackoverflow.com/questions/5851588/…El primer argumento en sys será el nombre del archivo actual, por lo que esto funcionará
fuente
Si está haciendo una importación inusual (por ejemplo, es un archivo de opciones), intente:
Tenga en cuenta que esto devolverá la ruta absoluta al archivo.
fuente
podemos intentar esto para obtener el nombre del script actual sin extensión.
fuente
Como el OP solicitó el nombre del archivo de script actual, preferiría
fuente
todas esas respuestas son geniales, pero tienen algunos problemas Es posible que no veas a primera vista.
definamos lo que queremos: queremos el nombre del script que se ejecutó, no el nombre del módulo actual, por
__file__
lo que solo funcionará si se usa en el script ejecutado, no en un módulo importado.sys.argv
también es cuestionable: ¿qué pasa si su programa fue llamado por pytest? o corredor pydoc? o si fue llamado por uwsgi?y - hay un tercer método para obtener el nombre del script, no lo he visto en las respuestas - Puedes inspeccionar la pila.
Otro problema es que usted (o algún otro programa) puede manipular
sys.argv
y__main__.__file__
puede estar presente, puede que no. Puede ser válido o no. ¡Al menos puedes comprobar si el script (el resultado deseado) existe!mi biblioteca bitranox / lib_programname en github hace exactamente eso:
__main__
está presente__main__.__file__
está presente__main__.__file__
un resultado válido (¿existe ese script?)por ese camino, mi solución está trabajando hasta ahora con
setup.py test
,uwsgi
,pytest
,pycharm pytest
,pycharm docrunner (doctest)
,dreampie
,eclipse
también hay un buen artículo de blog sobre ese problema de Dough Hellman, "Determinando el nombre de un proceso desde Python"
fuente
Mi solución rápida y sucia:
fuente
os.path
para dividir nombres de archivosos.path.abspath(__file__)
le dará una ruta absoluta (relpath()
disponible también).sys.argv[-1]
te dará un camino relativo.fuente
A partir de Python 3.5, simplemente puede hacer:
Ver más aquí: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Por ejemplo, tengo un archivo en mi directorio de usuarios
test.py
con este nombre :ejecutando estas salidas:
fuente