La funzione API C Python PyEval_EvalCode
consente di eseguire codice Python compilato. Voglio eseguire un blocco di codice Python come se fosse eseguito nell'ambito di una funzione, in modo che abbia il proprio dizionario di variabili locali che non influenzano lo stato globale.C Python: esecuzione di codice Python all'interno di un contesto
Questo sembra abbastanza facile da fare, dal momento che PyEval_EvalCode
consente di fornire un globale e locale dizionario:
PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
Il problema che ho incontrato ha a che fare con il modo in Python guarda in alto i nomi delle variabili. Si consideri il seguente codice, che eseguo con PyEval_EvalCode
:
myvar = 300
def func():
return myvar
func()
Questo semplice codice solleva in realtà un errore, perché Python è in grado di trovare la variabile myvar
dall'interno func
. Anche se myvar
si trova nel dizionario locale nell'ambito esterno, Python non lo copia nel dizionario locale nell'ambito interno. La ragione di ciò è la seguente:
Ogni volta che Python cerca un nome di variabile, controlla prima locals
, quindi controlla globals
e infine controlla builtins
. Nell'ambito del modulo , locals
e globals
si trova l'oggetto del dizionario SAME. Quindi la proposizione x = 5
nello scope del modulo inserirà x
nel dizionario locals
, che è anche il dizionario globals
. Ora, una funzione definita nello scope del modulo che deve cercare x
non troverà x
all'interno dell'ambito di funzione locals
, perché Python non copia i locus del modulo di visibilità in locals di scope di funzioni. Ma questo normalmente non è un problema, perché può trovare x
in globals
.
x = 5
def foo():
print(x) # This works because 'x' in globals() == True
E 'solo con nidificati funzioni, che Python sembra copiare i locali esterno portata in locali interni-scope. (Sembra anche a farlo pigramente, solo se sono necessari nell'ambito di applicazione interna.)
def foo():
x = 5
def bar():
print(x) # Now 'x' in locals() == True
bar()
Così il risultato di tutto questo è che, durante l'esecuzione di codice in modulo ambito, si deve assicurati che il tuo dizionario globale e il dizionario locale siano l'oggetto SAME, altrimenti le funzioni nell'ambito del modulo non saranno in grado di accedere alle variabili del modulo.
Ma nel mio caso, NON VOGLIO che il dizionario globale e il dizionario locale siano gli stessi. Quindi ho bisogno di un modo per dire all'interprete Python che sto eseguendo il codice allo scopo della funzione. C'è un modo per farlo? Ho esaminato lo PyCompileFlags
e gli argomenti aggiuntivi su PyEval_EvalCodeEx
e non riesco a trovare alcun modo per farlo.
@ Canale72 vedere sopra. – ecatmur