Akankah sesuatu seperti ini melakukan apa yang Anda butuhkan?
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()
Ini menghindari panggilan untuk diri sendiri untuk mengakses dekorator dan membiarkannya tersembunyi di namespace kelas sebagai metode biasa.
>>> import stackoverflow
>>> test = stackoverflow.Test()
>>> test.bar()
start magic
normal call
end magic
>>>
diedit untuk menjawab pertanyaan dalam komentar:
Cara menggunakan dekorator tersembunyi di kelas lain
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
Keluaran:
Normal:
start magic
normal call
end magic
Inherited:
start magic
override bar in
start magic
normal call
end magic
override bar out
end magic
Apa yang ingin Anda lakukan tidak mungkin. Ambil, misalnya, apakah kode di bawah ini terlihat valid atau tidak:
Itu, tentu saja, tidak valid karena
self
tidak didefinisikan pada saat itu. Hal yang sama berlaku karenaTest
tidak akan didefinisikan sampai kelas itu sendiri didefinisikan (yang sedang dalam proses). Saya menunjukkan kepada Anda potongan kode ini karena ini yang diubah menjadi potongan dekorator Anda.Jadi, seperti yang Anda lihat, mengakses instance dalam dekorator seperti itu tidak benar-benar mungkin karena dekorator diterapkan selama definisi fungsi / metode apa pun yang dilampirkan dan bukan selama instantiasi.
Jika Anda memerlukan akses tingkat kelas , coba ini:
sumber
sumber
@foo
, bukan@foo()
wrapper
menjadiself
?Saya menggunakan jenis dekorator ini dalam beberapa situasi debugging, ini memungkinkan mengesampingkan properti kelas dengan dekorasi, tanpa harus menemukan fungsi panggilan.
Ini adalah kode dekorator
Catatan: karena saya telah menggunakan dekorator kelas, Anda harus menggunakan @adecorator () dengan tanda kurung untuk menghias fungsi, bahkan jika Anda tidak memberikan argumen apa pun kepada konstruktor kelas dekorator.
sumber
Ini adalah salah satu cara untuk mengakses (dan telah menggunakan)
self
dari dalamdecorator
definisi di dalam kelas yang sama:Output (diuji pada
Python 2.7.10
):Contoh di atas konyol, tetapi berhasil.
sumber
Saya menemukan pertanyaan ini ketika meneliti masalah yang sangat mirip. Solusi saya adalah untuk membagi masalah menjadi dua bagian. Pertama, Anda perlu menangkap data yang ingin Anda asosiasikan dengan metode kelas. Dalam hal ini, handler_for akan mengaitkan perintah Unix dengan handler untuk output perintah itu.
Sekarang kita telah mengaitkan beberapa data dengan setiap metode kelas, kita perlu mengumpulkan data itu dan menyimpannya dalam atribut kelas.
sumber
Berikut ini adalah perluasan jawaban Michael Speer untuk mengambil beberapa langkah lebih jauh:
Dekorator metode instan yang mengambil argumen dan bertindak pada fungsi dengan argumen dan nilai kembali.
Lalu
sumber
Dekorator tampaknya lebih cocok untuk memodifikasi fungsionalitas seluruh objek (termasuk objek fungsi) dibandingkan fungsionalitas metode objek yang secara umum akan bergantung pada atribut instance. Sebagai contoh:
Outputnya adalah:
sumber
Anda dapat menghias dekorator:
sumber
Saya memiliki Implementasi Dekorator yang Mungkin Membantu
sumber
Deklarasikan di kelas batin. Solusi ini cukup solid dan direkomendasikan.
Hasil:
sumber