Respuestas:
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__)
.
__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
y import os.path
son completamente equivalentes.
import sys
print sys.argv[0]
Esto imprimirá foo.py
para python foo.py
, dir/foo.py
para python dir/foo.py
, etc. Es el primer argumento para python
. (Tenga en cuenta que después de py2exe sería foo.exe
).
python linkfile.py
, donde linkfile.py
es 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')
.
__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 :
__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-c
opció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 .
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.
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(...))
.
Desde Python 3.4 en adelante, según PEP 428 , la PurePath
clase del pathlib
módulo también se puede usar en cualquiera de los anteriores. Específicamente, pathlib.PurePath(...).name
extrae el nombre real del archivo y pathlib.PurePath(...).stem
extrae el nombre real del archivo sin su sufijo.
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.
rPython
paquete desde el R
idioma. Ese debe ser un caso excepcional que es demasiado difícil de manejar.
__main__
internamente, para usar al pasar variables entre R
y 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.
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])
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.
from pathlib import Path
primero.
pathlib
se introdujo en Python 3.4, por lo que debería funcionar a partir de Python 3.4.
Suponiendo que el nombre del archivo es foo.py
, el fragmento a continuación
import sys
print sys.argv[0][:-3]
o
import sys
print sys.argv[0][::-1][3:][::-1]
En cuanto a otras extensiones con más caracteres, por ejemplo, el nombre del archivo foo.pypy
import sys
print sys.argv[0].split('.')[0]
Si quieres extraer de una ruta absoluta
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
saldrá foo
El primer argumento en sys será el nombre del archivo actual, por lo que esto funcionará
import sys
print sys.argv[0] # will print the file name
Si está haciendo una importación inusual (por ejemplo, es un archivo de opciones), intente:
import inspect
print (inspect.getfile(inspect.currentframe()))
Tenga en cuenta que esto devolverá la ruta absoluta al archivo.
podemos intentar esto para obtener el nombre del script actual sin extensión.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
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"
Mi solución rápida y sucia:
__file__.split('/')[-1:][0]
os.path
para dividir nombres de archivos
os.path.abspath(__file__)
le dará una ruta absoluta ( relpath()
disponible también).
sys.argv[-1]
te dará un camino relativo.
A partir de Python 3.5, simplemente puede hacer:
from pathlib import Path
Path(__file__).stem
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 :
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
ejecutando estas salidas:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"