ฉันต้องการแทนที่__getattr__
วิธีการในชั้นเรียนเพื่อทำสิ่งที่แฟนซี แต่ฉันไม่ต้องการที่จะทำลายพฤติกรรมเริ่มต้น
วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร?
ฉันต้องการแทนที่__getattr__
วิธีการในชั้นเรียนเพื่อทำสิ่งที่แฟนซี แต่ฉันไม่ต้องการที่จะทำลายพฤติกรรมเริ่มต้น
วิธีที่ถูกต้องในการทำเช่นนี้คืออะไร?
คำตอบ:
การเอาชนะ__getattr__
ควรจะดี - __getattr__
ถูกเรียกว่าเป็นทางเลือกสุดท้ายเช่นหากไม่มีแอตทริบิวต์ในอินสแตนซ์ที่ตรงกับชื่อ ตัวอย่างเช่นถ้าคุณเข้าถึงfoo.bar
แล้ว__getattr__
จะถูกเรียกว่าถ้ามีแอตทริบิวต์ไม่มีที่เรียกว่าfoo
bar
หากแอตทริบิวต์นั้นเป็นคุณสมบัติที่คุณไม่ต้องการจัดการให้เพิ่มAttributeError
:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
อย่างไรก็ตามไม่เหมือน__getattr__
กัน__getattribute__
จะถูกเรียกก่อน (ใช้ได้กับคลาสสไตล์ใหม่เท่านั้นเช่นคลาสที่สืบทอดจากออบเจ็กต์) ในกรณีนี้คุณสามารถรักษาพฤติกรรมเริ่มต้นเช่น:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
__getattr__
- มีความคิดอะไรที่ต้องทำบ้าง? ( AttributeError: 'super' object has no attribute '__getattr__'
)
AttributeError
ไม่มีบริบทของคุณลักษณะในข้อยกเว้นที่เกิดขึ้น
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__
ควรใช้แทนself.__class__
ในกรณีที่มีการแทนที่ชั้นเรียน__repr__
หากต้องการขยายคำตอบของ Michael หากคุณต้องการรักษาการใช้งานที่เป็นค่าเริ่มต้น__getattr__
คุณสามารถทำได้ดังนี้:
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
ตอนนี้ข้อความแสดงข้อยกเว้นมีความหมายมากขึ้น:
>>> 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__
และ__getattribute__
?