Tôi muốn ghi đè __getattr__
phương thức trên một lớp để làm một cái gì đó lạ mắt nhưng tôi không muốn phá vỡ hành vi mặc định.
Cách chính xác để làm điều này là gì?
Tôi muốn ghi đè __getattr__
phương thức trên một lớp để làm một cái gì đó lạ mắt nhưng tôi không muốn phá vỡ hành vi mặc định.
Cách chính xác để làm điều này là gì?
Câu trả lời:
Ghi đè __getattr__
sẽ ổn - __getattr__
chỉ được gọi là giải pháp cuối cùng, tức là nếu không có thuộc tính nào trong trường hợp khớp với tên. Chẳng hạn, nếu bạn truy cập foo.bar
, thì __getattr__
sẽ chỉ được gọi nếu foo
không có thuộc tính được gọi bar
. Nếu thuộc tính là thuộc tính bạn không muốn xử lý, hãy nâng cao AttributeError
:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
Tuy nhiên, không giống như __getattr__
, __getattribute__
sẽ được gọi đầu tiên (chỉ hoạt động cho các lớp kiểu mới, tức là những lớp kế thừa từ đối tượng). Trong trường hợp này, bạn có thể duy trì hành vi mặc định như vậy:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
__getattr__
- bạn có biết phải làm gì không? ( AttributeError: 'super' object has no attribute '__getattr__'
)
AttributeError
không có bối cảnh của thuộc tính trong ngoại lệ args.
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__
nên được sử dụng thay vì self.__class__
trong trường hợp lớp ghi đè__repr__
Để mở rộng câu trả lời của Michael, nếu bạn muốn duy trì hành vi mặc định bằng cách sử dụng __getattr__
, bạn có thể làm như vậy:
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
Bây giờ thông báo ngoại lệ là mô tả nhiều hơn:
>>> 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__
và __getattribute__
?