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 oses necesario para que esto funcione. Añadiría esto a la respuesta.import osyimport os.pathson completamente equivalentes.Esto imprimirá
foo.pyparapython foo.py,dir/foo.pyparapython 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.pyes 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-mopció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íaNonecuando 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
PurePathclase delpathlibmódulo también se puede usar en cualquiera de los anteriores. Específicamente,pathlib.PurePath(...).nameextrae el nombre real del archivo ypathlib.PurePath(...).stemextrae 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
rPythonpaquete desde elRidioma. Ese debe ser un caso excepcional que es demasiado difícil de manejar.__main__internamente, para usar al pasar variables entreRypython, 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__).namedebería ser más idiomático. Además,Path(__file__).stemle da el nombre del script sin la.pyextensión.fuente
from pathlib import Pathprimero.pathlibse 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.pypySi quieres extraer de una ruta absoluta
saldrá
foofuente
__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.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:
__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,eclipsetambié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.pathpara 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.pycon este nombre :ejecutando estas salidas:
fuente