Reflection

Capacità di un linguaggio di modificare la propria struttura e il proprio comportamento a runtime.

Strumenti per reflectio

setattr(obj, key, val) Fa il set di un attributo key di valore val all’oggetto obj. Il nome può essere un valore calcolato a runtime, quindi il programma viene modificato.

__code__ Da la possibilità di intervenire sul codice di una funzione.

def f(a,b):
    pass
 
# si assegna il valore della funzione lambda alla funzione f
f.__code__ = (lambda x,y: x+y).__code__

Si può anche assegnare il codice di una funzione direttamente dall’interno di quella funzione. La funzione farà quello che deve fare, e utilizzerà il nuovo codice alla chiamata successiva.

def onetimeonly(msg):
    onetimeonly.__code__ = (lambda x: None).__code__
    print(msg)
	
onetimeonly("Bye bye")	# stampa Bye bye
onetimeonly("Bye bye")	# non fa nulla

exec, eval Compila codice python in forma di testo.

eval(expression, globals=None, locals=None)
exec(expression, globals=None, locals=None)

Se globals e locals non sono passati, verranno utilizzati quelli di default, dove si trova la chiamata. Il namespace locals può essere sovrascritto dal valore di __builtins__ in globals.

eval, a differenza di exec, non accetta variabili. exec e eval sono metodi poco sicuri.

python_book6