__getattribute__ ถูกเรียกเมื่อใดก็ตามที่มีการเข้าถึงคุณลักษณะ
class Foo(object):
def __init__(self, a):
self.a = 1
def __getattribute__(self, attr):
try:
return self.__dict__[attr]
except KeyError:
return 'default'
f = Foo(1)
f.a
สิ่งนี้จะทำให้เกิดการเรียกซ้ำแบบไม่สิ้นสุด return self.__dict__[attr]ผู้ร้ายที่นี่เป็นเส้น มาทำเป็นแกล้งกัน (มันใกล้ความจริงมากพอ) ว่ามีการเก็บแอตทริบิวต์ทั้งหมดไว้ในself.__dict__ชื่อของพวกเขา เส้น
f.a
ความพยายามที่จะเข้าถึงแอตทริบิวต์ของa fสายf.__getattribute__('a')นี้ แล้วพยายามที่จะโหลด__getattribute__ เป็นแอททริบิวต์ดังนั้น python จึงเรียกอีกครั้งว่าพยายามเข้าถึงแอททริบิว' นี่เป็นการเรียกซ้ำแบบไม่สิ้นสุดself.__dict____dict__self == ff.__getattribute__('__dict__')'__dict__
หาก__getattr__เคยถูกใช้มาแล้ว
- มันจะไม่ทำงานเพราะ
fมีaคุณสมบัติ
- ถ้ามันวิ่ง (ขอบอกว่าคุณถาม
f.b) แล้วมันจะไม่ได้รับการเรียกตัวไปพบ__dict__เพราะมันมีอยู่แล้วและ__getattr__มีการเรียกใช้เฉพาะในกรณีที่วิธีการอื่น ๆ ในการหาแอตทริบิวต์ได้ล้มเหลว
วิธี 'ถูกต้อง' ในการเขียนคลาสข้างต้นโดยใช้__getattribute__คือ
class Foo(object):
# Same __init__
def __getattribute__(self, attr):
return super(Foo, self).__getattribute__(attr)
super(Foo, self).__getattribute__(attr)ผูก__getattribute__เมธอดของซุปเปอร์คลาสที่ใกล้ที่สุด (อย่างเป็นทางการคลาสถัดไปในระเบียบวิธีการแก้ปัญหาของคลาสหรือ MRO) ไปยังวัตถุปัจจุบันselfจากนั้นเรียกมันและอนุญาตให้ทำงานได้
ปัญหาทั้งหมดนี้หลีกเลี่ยงได้โดยการใช้__getattr__ซึ่งทำให้ Python ทำสิ่งนั้นเป็นเรื่องปกติจนกระทั่งไม่พบคุณลักษณะ ณ จุดนั้น Python มือควบคุม__getattr__วิธีการของคุณและช่วยให้มันมาพร้อมกับบางสิ่งบางอย่าง
นอกจากนี้ยังเป็นที่น่าสังเกตว่าคุณสามารถใช้เป็น infinite __getattr__เรียกซ้ำกับ
class Foo(object):
def __getattr__(self, attr):
return self.attr
ฉันจะปล่อยให้สิ่งนั้นเป็นการออกกำลังกาย