2009-03-03 17 views
46

Supongamos que tengo dos módulos:¿Cómo obtener el nombre de archivo del módulo __main__ en Python?

a.py:

import b 
print __name__, __file__ 

b.py:

print __name__, __file__ 

que ejecute el archivo "a.py". Esta impresora:

b  C:\path\to\code\b.py 
__main__ C:\path\to\code\a.py 

Pregunta: ¿Cómo se obtiene la ruta de acceso al módulo de __main__ ("a.py" en este caso) desde el interior de la biblioteca "b.py"?

Respuesta

58
import __main__ 
print __main__.__file__ 
+1

¡Aseado! Es importante darse cuenta de que hay que importar __may__ - hice una conjetura al azar e intenté la segunda línea, pero falló - ahora sé por qué. –

+17

'__main__' no siempre tiene el atributo' __file__'. – jfs

+0

Sí, estaría bien si la respuesta pudiera actualizarse para mencionar eso. –

27

Tal vez esto hará el truco:

import sys 
from os import path 
print path.abspath(sys.modules['__main__'].__file__) 

Tenga en cuenta que, por seguridad, debe comprobar si el módulo __main__ tiene un atributo __file__. Si se crea de forma dinámica, o simplemente se está ejecutando en la consola Python interactiva, no va a tener un __file__: cheque

python 
>>> import sys 
>>> print sys.modules['__main__'] 
<module '__main__' (built-in)> 
>>> print sys.modules['__main__'].__file__ 
AttributeError: 'module' object has no attribute '__file__' 

Un simple hasattr() hará el truco para evitar el escenario 2, si eso es una posibilidad en tu aplicación

+0

Lo hace - ¡gracias! –

+0

¡Wunderbar! Me alegro de poder ayudar. Si esto responde su pregunta, ¿le importaría presionar el botón 'aceptar' en la pregunta? :-) –

+0

Si edita esto para usar el estilo "import __main__", volveré a aceptarlo, ya que es más detallado que la nueva respuesta aceptada. –

14

El código Python a continuación proporciona una funcionalidad adicional, incluyendo que funciona a la perfección con py2exe ejecutables.

Utilizo un código similar para hacer clic en Me gusta para encontrar las rutas relativas al script en ejecución, también conocido como __main__. como beneficio adicional, funciona multiplataforma incluyendo Windows.

import imp 
import os 
import sys 

def main_is_frozen(): 
    return (hasattr(sys, "frozen") or # new py2exe 
      hasattr(sys, "importers") # old py2exe 
      or imp.is_frozen("__main__")) # tools/freeze 

def get_main_dir(): 
    if main_is_frozen(): 
     # print 'Running from path', os.path.dirname(sys.executable) 
     return os.path.dirname(sys.executable) 
    return os.path.dirname(sys.argv[0]) 

# find path to where we are running 
path_to_script=get_main_dir() 

# OPTIONAL: 
# add the sibling 'lib' dir to our module search path 
lib_path = os.path.join(get_main_dir(), os.path.pardir, 'lib') 
sys.path.insert(0, lib_path) 

# OPTIONAL: 
# use info to find relative data files in 'data' subdir 
datafile1 = os.path.join(get_main_dir(), 'data', 'file1') 

Esperemos que el código de ejemplo anterior puede proporcionar información adicional sobre cómo determinar la ruta de acceso al script que corre ...

+1

Si cambia de directorio (con 'os.chdir') entre el inicio la secuencia de comandos y la llamada 'os.dirname (sys.argv [0])' el resultado no tiene sentido. – RobM

+0

Utilizo para hacer un módulo 'GLOBALS.py', que al menos es importado por el script principal, que ejecuta algo como el código anterior y almacena el resultado en una variable' MAINDIR', entonces puedo acceder a 'GLOBALS.MAINDIR' de cualquier otro módulo, sin preocuparse por el uso de 'os.chdir'. – Remi

+0

Si quería saber el directorio de inicio de su script y también desea usar 'os.chdir()', querrá guardar el 'os.getcwd()' inicial. Como el usuario estaba en Windows, quería demostrar algo que también funcionaría dentro del contexto de py2exe y congelación. – popcnt

1
import sys, os 

def getExecPath(): 
    try: 
     sFile = os.path.abspath(sys.modules['__main__'].__file__) 
    except: 
     sFile = sys.executable 
    return os.path.dirname(sFile) 

Esta función se activará para los programas Python y Cython compilados.

6

Otro método sería usar sys.argv[0].

import os 
import sys 

main_file = os.path.realpath(sys.argv[0]) if sys.argv[0] else None 

sys.argv[0] habrá una cadena vacía si Python se inicia con -c o si está marcada desde la consola de Python.

Cuestiones relacionadas