2009-11-04 12 views
111

Come posso ottenere un riferimento a un modulo all'interno di quel modulo? Inoltre, come posso ottenere un riferimento al pacchetto che contiene quel modulo?Python: Come posso ottenere un riferimento a un modulo all'interno del modulo stesso?

+5

Sospetto che stiate facendo questa domanda perché avete una variabile in ** scope del modulo ** (es. BLAH = 10 al di fuori di una funzione o classe), quindi una ** variabile di classe/funzione ** chiamata BLAH, e vuoi differenziare. Una domanda valida qui è: ** È necessario? ** Le regole dell'ambito sono notoriamente soggette a errori, soprattutto da parte dell'idiota che preleva il tuo codice dopo di te (cioè sei mesi dopo). Trucchi come questo sono raramente necessari; Cerco di evitarli completamente perché sono così spesso confusi e modificati in modo errato in seguito. –

+1

@ KevinJ.Rice "l''idiota' che prende il tuo codice dopo di te (cioè tu, 6 mesi dopo)" ha reso la mia giornata! – arctelix

+4

A chi importa perché sta facendo la domanda? Ci sono molti validi motivi per cui è necessario farlo. –

risposta

165
import sys 
current_module = sys.modules[__name__] 
+3

tranne per questo non sarà del tutto corretto se il modulo viene ricaricato; Non penso che ci sia un posto dove è garantito un riferimento, se ci fosse, ricaricare non funzionerebbe davvero, giusto? –

+10

Il ricaricamento riutilizza lo stesso oggetto modulo; non viene creato alcun nuovo oggetto modulo, quindi è ancora corretto di fronte al nuovo caricamento. – bukzor

14

Se si dispone di una classe in quel modulo, quindi la proprietà della classe è il __module__ nome di modulo della classe. In questo modo è possibile accedere al modulo tramite sys.modules[klass.__module__]. Questo funziona anche per le funzioni.

+4

In realtà, sembra che (almeno) per una funzione, la proprietà '__module__' non sia un modulo, ma una stringa; quindi un 'inspect.getabsfile (func .__ module __)' fallisce con "_TypeError: 'os' non è un modulo, classe, metodo, funzione, traceback, frame o codice oggetto_"; mentre 'inspect.getabsfile (sys.modules [o .__ module __])' sembra passare. – sdaau

+0

Grazie, risolto. – Michael

8

è possibile ottenere la nome del modulo corrente utilizzando __name__

Il riferimento del modulo può essere trovato nel dizionario sys.modules.

Vedi Python documentation

+3

Apprezzo il collegamento doc. –

3

più Una tecnica, che non importare il modulo sys, e forse - dipende dal vostro gusto - più semplice:

current_module = __import__(__name__) 

Essere consapevoli del fatto non v'è alcuna importazione. Python importa ogni modulo solo una volta.

+0

Questo sembra un modo davvero carino per evitare di importare sys. Oltre ad essere un po 'contro-intuitivo da leggere ci sono dei potenziali svantaggi di questo approccio? – JeremyDouglass

+0

@JeremyDouglass. Non che io sappia. __import__ è una funzione built-in legittima, documentata (l'unica funzione __xx__). Puoi sostituirlo con il pacchetto 'importlib' (dovrai importarlo). Forse - non mi è mai successo - potresti avere un problema con l'importazione relativa/assoluta, se un modulo con lo stesso nome è disponibile in sys.path, nel qual caso puoi risolverlo con l'argomento 'livello' della funzione. – Uri

1

È possibile passare in dall'esterno:

mymod.init(mymod) 

Non è l'ideale ma funziona per il mio attuale caso d'uso.

Problemi correlati