Czy coś takiego zrobi to, czego potrzebujesz?
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()
Pozwala to uniknąć wywołania self w celu uzyskania dostępu do dekoratora i pozostawia go ukrytym w przestrzeni nazw klas jako zwykłą metodę.
>>> import stackoverflow
>>> test = stackoverflow.Test()
>>> test.bar()
start magic
normal call
end magic
>>>
zredagowano, by odpowiedzieć na pytanie w komentarzach
Jak korzystać z ukrytego dekoratora w innej klasie
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
Wynik:
Normal:
start magic
normal call
end magic
Inherited:
start magic
override bar in
start magic
normal call
end magic
override bar out
end magic
To, czego chcesz, nie jest możliwe. Weźmy na przykład, czy poniższy kod wygląda na prawidłowy:
To oczywiście nie jest poprawne, ponieważ
self
nie jest zdefiniowane w tym momencie. To samo dotyczyTest
tego, że nie zostanie zdefiniowana, dopóki nie zostanie zdefiniowana sama klasa (która jest w trakcie). Pokazuję ci ten fragment kodu, ponieważ w to właśnie przekształca się Twój fragment dekoratora.Tak więc, jak widać, dostęp do instancji w takim dekoratorze nie jest tak naprawdę możliwy, ponieważ dekoratory są stosowane podczas definiowania dowolnej funkcji / metody, do której są dołączone, a nie podczas tworzenia instancji.
Jeśli potrzebujesz dostępu na poziomie klasy , spróbuj tego:
źródło
źródło
@foo
, a nie@foo()
wrapper
byćself
?Używam tego typu dekoratora w niektórych sytuacjach debugowania, umożliwia on nadpisywanie właściwości klas poprzez dekorowanie, bez konieczności znajdowania funkcji wywołującej.
Oto kod dekoratora
Uwaga: ponieważ użyłem dekoratora klas, musisz użyć @adecorator () z nawiasami kwadratowymi, aby ozdobić funkcje, nawet jeśli nie przekażesz żadnych argumentów do konstruktora klasy dekoratora.
źródło
Jest to jeden ze sposobów dostępu (i był używany)
self
z wnętrzadecorator
zdefiniowanej w tej samej klasie:Wyjście (testowane
Python 2.7.10
):Powyższy przykład jest głupi, ale działa.
źródło
Znalazłem to pytanie, badając bardzo podobny problem. Moim rozwiązaniem jest podzielenie problemu na dwie części. Najpierw musisz przechwycić dane, które chcesz skojarzyć z metodami klas. W takim przypadku funkcja handler_for skojarzy polecenie systemu Unix z obsługą danych wyjściowych tego polecenia.
Teraz, gdy powiązaliśmy pewne dane z każdą metodą klasową, musimy zebrać te dane i przechowywać je w atrybucie klasy.
źródło
Oto rozszerzenie odpowiedzi Michaela Speera, aby pójść o kilka kroków dalej:
Dekorator metody instancji, który przyjmuje argumenty i działa na funkcji z argumentami i wartością zwracaną.
I wtedy
źródło
Dekoratory wydają się lepiej przystosowane do modyfikowania funkcjonalności całego obiektu (łącznie z obiektami funkcyjnymi) w porównaniu z funkcjonalnością metody obiektu, która na ogół będzie zależeć od atrybutów instancji. Na przykład:
Wynik to:
źródło
Możesz ozdobić dekoratora:
źródło
Mam implementację dekoratorów, które mogą pomóc
źródło
Zadeklaruj w klasie wewnętrznej. To rozwiązanie jest całkiem solidne i polecane.
Wynik:
źródło