Algo assim faria o que você precisa?
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()
Isso evita que a chamada pessoal acesse o decorador e o deixa oculto no namespace da classe como um método regular.
>>> import stackoverflow
>>> test = stackoverflow.Test()
>>> test.bar()
start magic
normal call
end magic
>>>
editado para responder a pergunta nos comentários:
Como usar o decorador oculto em outra classe
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
Resultado:
Normal:
start magic
normal call
end magic
Inherited:
start magic
override bar in
start magic
normal call
end magic
override bar out
end magic
O que você está querendo fazer não é possível. Veja, por exemplo, se o código abaixo parece válido ou não:
É claro que não é válido, pois
self
não está definido nesse momento. O mesmo valeTest
, pois não será definido até que a própria classe seja definida (a qual está no processo de). Estou mostrando esse snippet de código, porque é nele que o snippet do decorador se transforma.Portanto, como você pode ver, acessar a instância em um decorador como esse não é realmente possível, pois os decoradores são aplicados durante a definição de qualquer função / método ao qual estão anexados e não durante a instanciação.
Se você precisar de acesso em nível de classe , tente o seguinte:
fonte
fonte
@foo
, não@foo()
wrapper
serself
?Eu uso esse tipo de decorador em algumas situações de depuração, ele permite substituir as propriedades da classe decorando, sem precisar encontrar a função de chamada.
Aqui está o código do decorador
Nota: como usei um decorador de classe, você precisará usar @adecorator () com os colchetes para decorar funções, mesmo se você não passar nenhum argumento para o construtor de classes do decorador.
fonte
Esta é uma maneira de acessar (e ter usado)
self
de dentro de umdecorator
definido dentro da mesma classe:Saída (testada em
Python 2.7.10
):O exemplo acima é bobo, mas funciona.
fonte
Encontrei essa pergunta ao pesquisar um problema muito semelhante. Minha solução é dividir o problema em duas partes. Primeiro, você precisa capturar os dados que deseja associar aos métodos de classe. Nesse caso, handler_for associará um comando Unix ao manipulador para a saída desse comando.
Agora que associamos alguns dados a cada método de classe, precisamos coletar esses dados e armazená-los em um atributo de classe.
fonte
Aqui está uma expansão da resposta de Michael Speer para dar alguns passos adiante:
Um decorador de método de instância que recebe argumentos e age em uma função com argumentos e um valor de retorno.
E depois
fonte
Os decoradores parecem mais adequados para modificar a funcionalidade de um objeto inteiro (incluindo objetos de função) versus a funcionalidade de um método de objeto que, em geral, dependerá dos atributos da instância. Por exemplo:
A saída é:
fonte
Você pode decorar o decorador:
fonte
Eu tenho uma implementação de decoradores que podem ajudar
fonte
Declarar na classe interna. Esta solução é bastante sólida e recomendada.
O resultado:
fonte