2009-03-03 19 views
46

Supponiamo che io ho due moduli:Come ottenere il nome file del modulo __main__ in Python?

a.py:

import b 
print __name__, __file__ 

b.py:

print __name__, __file__ 

ho eseguire il file "a.py". Questo stampa:

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

Domanda: Come posso ottenere il percorso del modulo __main__ ("a.py" in questo caso) all'interno della libreria "b.py"?

risposta

58
import __main__ 
print __main__.__file__ 
+1

Neat! È importante capire che è necessario importare __main__ - ho fatto un'ipotesi casuale e ho effettivamente provato la seconda riga, ma non è riuscita - ora so perché. –

+17

'__main__' non ha sempre attributo' __file__'. – jfs

+0

Sì, sarebbe bello se la risposta potesse essere aggiornata per dirlo. –

27

Forse questo farà il trucco:

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

Si noti che, per sicurezza, si dovrebbe verificare se il modulo __main__ ha un attributo __file__. Se è creato dinamicamente, o è solo in esecuzione nella console interattiva di Python, non avrà un __file__: assegno

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

Un semplice hasattr() farà il trucco per evitare lo scenario 2, se questo è una possibilità nella tua app.

+0

Sì, grazie! –

+0

Wunderbar! Sono contento di poterti aiutare. Se questo risponde alla tua domanda, ti dispiacerebbe premere il pulsante "Accetto" nella domanda? :-) –

+0

Se lo modifichi per utilizzare lo stile "import __main__", tornerò ad accettare, poiché è più dettagliato della nuova risposta accettata. –

14

Il codice python seguito fornisce funzionalità aggiuntive, tra cui che funziona perfettamente con py2exe eseguibili.

Uso un codice simile a questo per trovare percorsi relativi allo script in esecuzione, ovvero __main__. come ulteriore vantaggio, funziona su più piattaforme, incluso 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') 

Speriamo che il codice di esempio precedente in grado di fornire ulteriori indizi su come determinare il percorso dello script in esecuzione ...

+1

Se cambi la directory (con 'os.chdir') tra il lancio lo script e chiamando 'os.dirname (sys.argv [0])' il risultato non ha senso. – RobM

+0

Io uso per creare un modulo 'GLOBALS.py', che è almeno importato dallo script principale, che esegue qualcosa come il codice precedente e memorizza il risultato in una variabile' MAINDIR', quindi posso accedere a 'GLOBALS.MAINDIR' da qualsiasi altro modulo, senza preoccuparsi dell'uso di 'os.chdir'. – Remi

+0

Se volevi sapere la directory di partenza del tuo script e vuoi anche usare 'os.chdir()', vorrai salvare l'iniziale 'os.getcwd()'. Dato che l'utente era su Windows, volevo dimostrare qualcosa che avrebbe funzionato anche nel contesto di py2exe e blocco. – 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) 

questa funzione è operativa per i programmi Python e Cython compilati.

6

Un altro metodo sarebbe utilizzare sys.argv[0].

import os 
import sys 

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

sys.argv[0] sarà una stringa vuota se Python ottiene iniziare con -c o se controllati dalla console Python.

Problemi correlati