Sono abbastanza nuovo per Python, e ho giocato un po 'con esso per un po' ora. Ho giocato con la funzione integrata compile()
, insieme a marshal
e l'integrato exec()
. Ho notato alcune cose per cui non riesco a trovare le risposte. Si consideri il seguente script:Python exec() di un oggetto con codice di marshalling
#!/usr/bin/python
def foo():
print "Inside foo()..."
def main():
print "This is a simple script that should count to 10."
for i in range(0, 10):
print "This is iteration number", i
foo()
if __name__ == "__main__":
main()
Questo funziona bene quando viene eseguito attraverso qualcosa di simile:
with open('simple.py', 'r') as f:
code = f.read()
exec code
Tuttavia, quando viene compilato in un oggetto codice tramite compile()
, serializzato via marshal.dump()
, salvato in un file e poi leggere dal file, deserializzato tramite marshal.load()
ed eseguito con exec()
, si verifica un errore con NameError
che indica che il nome globale foo
non è definito.
Ho esaminato l'output fornito da dir()
e quando I import()
il codice, posso vedere che ha una definizione per foo()
. Ho anche notato che con l'utilizzo dis.dis()
sul codice oggetto deserializzato (letto tramite marshal.load()
), l'unica cosa che vedo è il LOAD_NAME
e CALL_FUNCTION
per main()
(al contrario di fare qualcosa di simile exec 'import %s' % modname
, e poi facendo dis.dis(sys.modules[modname])
, che ti dà l'intero smontaggio come previsto).
Sono corretto che esiste una sorta di tabella di ricerca che consente a import()
di consultare questi indirizzi? (Per la cronaca, ho controllato http://svn.python.org/projects/python/trunk/Lib/py_compile.py e le uniche differenze che ho potuto vedere nel bytecode che è stato generato tramite py_compile.compile()
e l'compile()
integrato era il imp.get_magic()
, insieme al timestamp a 32 bit). Se esiste un tale tavolo, c'è un buon modo per consultarlo?
Grazie!
quando viene serializzato tramite 'marshal.dump()'? il file di testo? – Claudiu
L'oggetto codice per quello script generato tramite 'compile()'. – user1633448
Cosa intendi? Quanto segue sembra funzionare: con open ('simple.py', 'r') come f: code = f.read() con open ('simple.mash', 'w') come f: marshal.dump (codice, f) con aperta ('simple.mash', 'r') come f: codice = marshal.load (f) codice exec – Dhara