2010-11-11 9 views

Respuesta

327

Use __file__. Si desea omitir la parte del directorio (que podría estar presente), puede usar os.path.basename(__file__).

+9

Python 3.2: "excepción' NameError: NameError (" nombre global '__file__' no está definido",) '" – sdaau

+6

@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. –

+1

Al menos para Python 2.7, creo que se requiere un 'import os' para que esto funcione. Añadiría esto a la respuesta. –

86
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 de python. (. Tenga en cuenta que después de py2exe sería foo.exe)

+0

No funcionará para enlaces simbólicos. –

+27

@DenisMalinovsky: defina "no funcionará". Si llama a 'python linkfile.py', donde' linkfile.py' es un enlace simbólico a 'realfile.py',' sys.argv [0] 'será' 'linkfile.py'', que puede o no ser Lo que quieras; es ciertamente lo que * espero *. '__file__' es lo mismo: será' linkfile.py'. Si quiere encontrar ''filefile.py'' de' 'linkfile.py'', intente 'os.path.realpath (' linkfile.py ')'. –

+6

+1 porque es (a) un poco más limpio y (b) seguirá funcionando en el módulo (donde la variable __file__ sería el archivo del módulo, no el ejecutado). – robert

6

Prueba esto:

print __file__ 
41

Tenga en cuenta que __file__ le dará al archivo donde reside el código, que puede ser importado y diferente del archivo principal está interpretando. Para obtener el archivo principal, el módulo especial __main__ se puede utilizar:

import __main__ as main 
print(main.__file__) 

en cuenta que __main__.__file__ obras en Python 2.7, pero no en 3.2, a fin de utilizar la importación-como sintaxis de arriba para que sea portátil.

+0

Esto funciona en muchos casos, pero no cuando estoy usando el paquete 'rPython' del lenguaje' R'. Ese debe ser un caso excepcional que es demasiado difícil de manejar. – Leonid

+0

De hecho, el paquete rPython integra el intérprete python, lo que significa que no hay un archivo 'principal' como el que hay cuando python se ejecuta por sí mismo (encontrará el mismo comportamiento cada vez que se incorpore python). Sí importa internamente '__main__', para utilizar al pasar variables entre' R' y 'python', por lo que sería relativamente fácil hacer que establezca' __main __.__ file__' antes de llamar a cualquier otra cosa, pero ni siquiera estoy seguro de qué sería un valor apropiado en este caso. – Perkins

29

Las respuestas de arriba son buenas. Pero encontré este método más eficiente usando los resultados anteriores.
Esto da como resultado que el nombre del archivo de script real no sea una ruta.

import sys  
import os  
file_name = os.path.basename(sys.argv[0]) 
+0

Sí, esto me parece más limpio. Gracias. – dentex

24

Para completarlo, pensé que valdría la pena que resume los distintos resultados posibles y el suministro de referencias para el comportamiento exacto de cada uno:

  • __file__ es el archivo que se está ejecutando, como se detalla en la official documentation:

    __file__ is the pathname of the file from which the module was loaded, if it was loaded from a file. The __file__ attribute may be missing for certain types of modules, such as C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file.

    From Python3.4 en adelante, por issue 18416, __file__ es siempre una ruta absoluta, a menos que el archivo que se está ejecutando actualmente sea un script que se haya ejecutado directamente (no a través del intérprete con la opción de línea de comando -m) utilizando una ruta relativa.

  • __main__.__file__ (requiere importar __main__) simplemente accede a la mencionada __file__ atributo de la main module, por ejemplo de la secuencia de comandos que se invocó desde la línea de comandos.

  • sys.argv[0] (requiere la importación de sys) es el nombre del script que se invoca desde la línea de comandos, y podría ser una ruta absoluta, como se detalla en la official documentation:

    argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c' . If no script name was passed to the Python interpreter, argv[0] is the empty string.

    Como se mencionó en another answer to this question, Python las secuencias de comandos 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] tendría el nombre del ejecutable en lugar del nombre del archivo principal Python dentro de ese ejecutable).


os.path.basename() podrá invocarse en cualquiera de los anteriores con el fin de extraer el nombre de archivo real.

4

El primer argumento en sys será el nombre del archivo actual, de modo que esto funcionará

import sys 
    print sys.argv[0] # will print the file name 
2

Suponiendo que el nombre del archivo es foo.py, el siguiente fragmento de código

import sys 
print sys.argv[0][:-3] 

o

import sys 
print sys.argv[0][::-1][3:][::-1] 

dará salida foo

+1

sys.argv [0] [: - 3] haría –

+0

@konpsych que es más elegante – xtonousou

+0

Hay una gran diferencia entre '__file__' y' sys.argv [0] ', consulte https://stackoverflow.com/questions/5851588/difference-between-file-and-sys-argv0 –

-1

Mi rápida solución sucia:

__file__.split('/')[-1:][0] 
+0

Mejor uso 'os.path' para dividir nombres de archivos –

0

Esto funcionó para mí con Python 3,6

import inspect, os 
print (inspect.getfile(inspect.currentframe())) 
Cuestiones relacionadas