Debido a reglas de alcance de Python, una función decorada en general no puede acceder a cualquier variable en el decorador. Sin embargo, puesto que las funciones pueden tener atributos arbitrarios asignados a ellos, podría hacer algo como lo siguiente en el decorador para conseguir un efecto similar:
def funcDec(func):
localVariable = "I'm a local string"
def wrapped(*args):
print("Calling localVariable from funcDec " + localVariable)
func(*args)
print("done with calling f1")
wrapped.attrib = localVariable
return wrapped
@funcDec
def f1(x, y):
print(x + y)
print('f1.attrib: {!r}'.format(f1.attrib))
f1(2, 3)
que produciría el siguiente resultado:
Calling localVariable from decorator I'm a local string
5
f1.attrib: "I'm a local string"
done with calling f1
Alguien preguntó si esto podría aplicarse a los métodos de una clase: La respuesta es "sí", pero debe hacer referencia al método ya sea a través de la clase en sí o la instancia de que pasó como self
argumento. Ambas técnicas se muestran a continuación. Es preferible usar self
ya que hace que el código sea independiente del nombre de la clase en la que se encuentra.
class Test(object):
@funcDec
def f1(self):
print('{}.f1() called'.format(self.__class__.__name__))
print('self.f1.attrib: {!r}'.format(self.f1.attrib)) # Preferred.
print('Test.f1.attrib: {!r}'.format(Test.f1.attrib)) # Also works.
print()
test = Test()
test.f1()
Salida:
Calling localVariable from funcDec I'm a local string
Test.f1() called
self.f1.attrib: "I'm a local string"
Test.f1.attrib: "I'm a local string"
done with calling f1
Ver también: http://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping_and_dynamic_scoping – georg