Phương pháp __getattribute__
cần được viết cẩn thận để tránh vòng lặp vô hạn. Ví dụ:Python: tránh các vòng vô hạn trong __getattribute__
class A:
def __init__(self):
self.x = 100
def __getattribute__(self, x):
return self.x
>>> a = A()
>>> a.x # infinite looop
RuntimeError: maximum recursion depth exceeded while calling a Python object
class B:
def __init__(self):
self.x = 100
def __getattribute__(self, x):
return self.__dict__[x]
>>> b = B()
>>> b.x # infinite looop
RuntimeError: maximum recursion depth exceeded while calling a Python object
Do đó chúng ta cần phải viết phương pháp theo cách này:
class C:
def __init__(self):
self.x = 100
def __getattribute__(self, x):
# 1. error
# AttributeError: type object 'object' has no attribute '__getattr__'
# return object.__getattr__(self, x)
# 2. works
return object.__getattribute__(self, x)
# 3. works too
# return super().__getattribute__(x)
Câu hỏi của tôi là tại sao object.__getattribute__
phương pháp làm việc? Từ đâu object
nhận phương thức __getattribute__
? Và nếu object
không có bất kỳ __getattribute__
, thì chúng tôi chỉ đang gọi cùng một phương thức trên lớp C
nhưng thông qua siêu lớp. Tại sao, sau đó gọi phương thức thông qua siêu lớp không dẫn đến một vòng lặp vô hạn?
Bạn có chắc là bạn cần '__getattribute__' chứ không phải' __getattr__'? –
Có, vì tôi cần phải đánh chặn TẤT CẢ thuộc tính tìm nạp trong lớp của tôi. Nhưng ngay cả khi tôi không làm vậy, tôi vẫn muốn biết chi tiết đầy đủ về lý do tại sao điều này là như vậy. – treecoder
Vâng, bạn phải chặn * tất cả * quyền truy cập thuộc tính hoặc bạn không :-) –