2010-02-22 10 views
12

Dato che ho l'oggetto codice per un modulo, come posso ottenere l'oggetto modulo corrispondente?Come generare un oggetto modulo da un oggetto codice in Python

Sembra che moduleNames = {}; exec code in moduleNames faccia qualcosa di molto vicino a quello che voglio. Restituisce i globali dichiarati nel modulo in un dizionario. Ma se voglio l'oggetto modulo reale, come ottenerlo?

MODIFICA: Sembra che tu possa rotolare il tuo oggetto modulo. Il tipo di modulo non viene convenientemente documentato, ma si può fare qualcosa di simile:

import sys 
module = sys.__class__ 
del sys 
foo = module('foo', 'Doc string') 
foo.__file__ = 'foo.pyc' 
exec code in foo.__dict__ 
+0

L'accesso preferenziale il punto per il tipo di modulo è 'types.ModuleType'. –

risposta

19

Come commento indica già, in Python di oggi il modo preferito per istanziare i tipi che non hanno nomi built-in è quello di chiamare il tipo ottenuto mediante il modulo types dalla libreria standard:

>>> import types 
>>> m = types.ModuleType('m', 'The m module') 

Si noti che questo non inserire automaticamente il nuovo modulo in sys.modules:

>>> import sys 
>>> sys.modules['m'] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 'm' 

Questo è un compito è necessario eseguire manualmente:

>>> sys.modules['m'] = m 
>>> sys.modules['m'] 
<module 'm' (built-in)> 

Questo può essere importante, in quanto oggetto del codice di un modulo viene eseguito normalmente dopo del aggiunto sys.modules modulo - per esempio, è perfettamente corretto per tale codice per fare riferimento a sys.modules[__name__] e che non riuscirebbe (KeyError) se si è dimenticato questo passaggio. Dopo questo passo, e l'impostazione m.__file__ come hai già nella tua modifica,

>>> code = compile("a=23", "m.py", "exec") 
>>> exec code in m.__dict__ 
>>> m.a 
23 

(o Python 3 equivalente dove exec è una funzione, se Python 3 è quello che si sta utilizzando, naturalmente; -) è corretto (ovviamente, normalmente avrai ottenuto l'oggetto codice con mezzi più sottili rispetto alla compilazione di una stringa, ma ciò non è rilevante per la tua domanda ;-).

Nelle versioni più vecchie di Python si sarebbe usato il modulo al posto del modulo typesnew di fare un nuovo oggetto modulo alla partenza, ma new è deprecato dal Python 2.6 e rimosso in Python 3.

Problemi correlati