Jadi, saya bermain dengan dekorator di Python 2.6, dan saya mengalami kesulitan untuk membuatnya bekerja. Ini file kelas saya:
class testDec:
@property
def x(self):
print 'called getter'
return self._x
@x.setter
def x(self, value):
print 'called setter'
self._x = value
Apa yang saya pikir dimaksudkan adalah memperlakukan x
seperti properti, tetapi panggil fungsi ini di get and set. Jadi, saya menyalakan IDLE dan memeriksanya:
>>> from testDec import testDec
from testDec import testDec
>>> t = testDec()
t = testDec()
>>> t.x
t.x
called getter
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "testDec.py", line 18, in x
return self._x
AttributeError: testDec instance has no attribute '_x'
>>> t.x = 5
t.x = 5
>>> t.x
t.x
5
Jelas panggilan pertama berfungsi seperti yang diharapkan, karena saya memanggil pengambil, dan tidak ada nilai default, dan gagal. Oke, bagus, saya mengerti. Namun, panggilan untuk menetapkan t.x = 5
tampaknya membuat properti baru x
, dan sekarang pengambil tidak berfungsi!
Apa yang saya lewatkan?
Jawaban:
Anda tampaknya menggunakan kelas gaya lama klasik di python 2. Agar properti berfungsi dengan benar, Anda harus menggunakan kelas gaya baru (di python 2 Anda harus mewarisi dari
object
). Cukup nyatakan kelas Anda sebagaiMyClass(object)
:Berhasil:
Detail lain yang mungkin menyebabkan masalah adalah bahwa kedua metode membutuhkan nama yang sama agar properti berfungsi. Jika Anda mendefinisikan setter dengan nama yang berbeda seperti ini, itu tidak akan berfungsi :
Dan satu hal lagi yang tidak sepenuhnya mudah dikenali pada awalnya, adalah urutannya: Sang pengambil harus ditentukan terlebih dahulu . Jika Anda menentukan setter terlebih dahulu, Anda mendapatkan
name 'x' is not defined
kesalahan.sumber
Hanya catatan untuk orang lain yang tersandung di sini mencari pengecualian ini: kedua fungsi harus memiliki nama yang sama. Memberi nama metode sebagai berikut akan menghasilkan pengecualian:
Sebaliknya berikan kedua metode nama yang sama
Penting juga untuk dicatat bahwa urutan deklarasi penting. Pengambil harus ditentukan sebelum setter dalam file atau Anda akan mendapatkan
NameError: name 'x' is not defined
sumber
NameError: name 'x' is not defined
pengecualian.Anda perlu menggunakan kelas gaya baru yang Anda lakukan dengan menurunkan kelas Anda dari objek:
Maka itu harus bekerja.
sumber
Jika ada yang datang ke sini dari google, di samping jawaban di atas saya ingin menambahkan bahwa ini perlu perhatian ketika meminta setter dari
__init__
metode kelas Anda berdasarkan jawaban ini Secara khusus:sumber
__init__
metode, tetapi fron metode lain di kelas.