¿Algo como esto haría lo que necesitas?
class Test(object):
def _decorator(foo):
def magic( self ) :
print "start magic"
foo( self )
print "end magic"
return magic
@_decorator
def bar( self ) :
print "normal call"
test = Test()
test.bar()
Esto evita la llamada a sí mismo para acceder al decorador y lo deja oculto en el espacio de nombres de la clase como un método regular.
>>> import stackoverflow
>>> test = stackoverflow.Test()
>>> test.bar()
start magic
normal call
end magic
>>>
editado para responder preguntas en los comentarios:
Cómo usar el decorador oculto en otra clase
class Test(object):
def _decorator(foo):
def magic( self ) :
print "start magic"
foo( self )
print "end magic"
return magic
@_decorator
def bar( self ) :
print "normal call"
_decorator = staticmethod( _decorator )
class TestB( Test ):
@Test._decorator
def bar( self ):
print "override bar in"
super( TestB, self ).bar()
print "override bar out"
print "Normal:"
test = Test()
test.bar()
print
print "Inherited:"
b = TestB()
b.bar()
print
Salida:
Normal:
start magic
normal call
end magic
Inherited:
start magic
override bar in
start magic
normal call
end magic
override bar out
end magic
Lo que quieres hacer no es posible. Tomemos, por ejemplo, si el siguiente código parece válido o no:
Por supuesto, no es válido ya
self
que no está definido en ese punto. Lo mismo ocurreTest
ya que no se definirá hasta que se defina la clase en sí (que está en proceso de). Te estoy mostrando este fragmento de código porque esto es en lo que se transforma tu fragmento de decorador.Entonces, como puede ver, acceder a la instancia en un decorador como ese no es realmente posible ya que los decoradores se aplican durante la definición de cualquier función / método al que estén conectados y no durante la creación de instancias.
Si necesita acceso a nivel de clase , intente esto:
fuente
fuente
@foo
, no@foo()
wrapper
serself
?Utilizo este tipo de decorador en algunas situaciones de depuración, permite anular las propiedades de clase decorando, sin tener que encontrar la función de llamada.
Aquí está el código del decorador
Nota: debido a que he usado un decorador de clases, deberá usar @adecorator () con los corchetes para decorar funciones, incluso si no pasa ningún argumento al constructor de la clase de decorador.
fuente
Esta es una forma de acceder (y haber utilizado)
self
desde dentro de undecorator
definido dentro de la misma clase:Salida (probada
Python 2.7.10
):El ejemplo anterior es tonto, pero funciona.
fuente
Encontré esta pregunta mientras investigaba un problema muy similar. Mi solución es dividir el problema en dos partes. Primero, necesita capturar los datos que desea asociar con los métodos de clase. En este caso, handler_for asociará un comando Unix con el controlador para la salida de ese comando.
Ahora que hemos asociado algunos datos con cada método de clase, necesitamos recopilar esos datos y almacenarlos en un atributo de clase.
fuente
Aquí hay una expansión de la respuesta de Michael Speer para ir más allá:
Un decorador de métodos de instancia que toma argumentos y actúa sobre una función con argumentos y un valor de retorno.
Y entonces
fuente
Los decoradores parecen más adecuados para modificar la funcionalidad de un objeto completo (incluidos los objetos de función) frente a la funcionalidad de un método de objeto que, en general, dependerá de los atributos de la instancia. Por ejemplo:
El resultado es:
fuente
Puedes decorar el decorador:
fuente
Tengo una implementación de decoradores que podría ayudar
fuente
Declarar en clase interior. Esta solución es bastante sólida y recomendada.
El resultado:
fuente