Saya ingin mengganti __getattr__
metode pada kelas untuk melakukan sesuatu yang mewah tetapi saya tidak ingin merusak perilaku default.
Apa cara yang benar untuk melakukan ini?
Saya ingin mengganti __getattr__
metode pada kelas untuk melakukan sesuatu yang mewah tetapi saya tidak ingin merusak perilaku default.
Apa cara yang benar untuk melakukan ini?
Jawaban:
Mengesampingkan __getattr__
harus baik - __getattr__
hanya disebut sebagai upaya terakhir yaitu jika tidak ada atribut dalam contoh yang cocok dengan namanya. Misalnya, jika Anda mengakses foo.bar
, maka __getattr__
hanya akan dipanggil jika foo
tidak memiliki atribut yang dipanggil bar
. Jika atributnya adalah atribut yang tidak ingin Anda tangani, naikkan AttributeError
:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
Namun, tidak seperti __getattr__
, __getattribute__
akan dipanggil dulu (hanya berfungsi untuk kelas gaya baru yaitu yang diwariskan dari objek). Dalam hal ini, Anda dapat mempertahankan perilaku default seperti:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
__getattr__
- ada ide apa yang harus dilakukan? ( AttributeError: 'super' object has no attribute '__getattr__'
)
AttributeError
tanpa konteks atribut dalam args pengecualian.
class A(object):
def __init__(self):
self.a = 42
def __getattr__(self, attr):
if attr in ["b", "c"]:
return 42
raise AttributeError("%r object has no attribute %r" %
(self.__class__.__name__, attr))
>>> a = A()
>>> a.a
42
>>> a.b
42
>>> a.missing
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: 'A' object has no attribute 'missing'
>>> hasattr(a, "b")
True
>>> hasattr(a, "missing")
False
self.__class__.__name__
harus digunakan sebagai pengganti self.__class__
kalau-kalau kelas menimpa__repr__
Untuk memperluas jawaban Michael, jika Anda ingin mempertahankan perilaku default menggunakan __getattr__
, Anda dapat melakukannya seperti:
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
Sekarang pesan pengecualian lebih deskriptif:
>>> foo.something
42
>>> foo.error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getattr__
AttributeError: 'Foo' object has no attribute 'error'
__getattr__
dan __getattribute__
?