gpt4 book ai didi

python - 为什么在描述符类的 __get__ 中需要 "if instance is None"?

转载 作者:太空狗 更新时间:2023-10-30 02:44:26 25 4
gpt4 key购买 nike

我从 Effective Python item 31 中得到以下示例:

from weakref import WeakKeyDictionary
class Grade(object):
def __init__(self):
self._values = WeakKeyDictionary()
def __get__(self, instance, instance_type):
if instance is None: return self
return self._values.get(instance, 0)

def __set__(self, instance, value):
if not (0 <= value <= 100):
raise ValueError('Grade must be between 0 and 100')
self._values[instance] = value


# Example 16
class Exam(object):
math_grade = Grade()
writing_grade = Grade()
science_grade = Grade()

first_exam = Exam()
first_exam.writing_grade = 82
second_exam = Exam()
second_exam.writing_grade = 75
print('First ', first_exam.writing_grade, 'is right')
print('Second', second_exam.writing_grade, 'is right')

我想不出任何理由在 __get__ 中使用 if instance is None: return selfExam(或其他使用 Grade 的潜在类(class))实例如何成为 None

最佳答案

Python 将在访问类上的描述符时为实例传入 None

在这种情况下,通过返回 self,您可以访问类上的描述符对象,而无需绕过协议(protocol)(通过访问 ClassObj.__dict__['name_of_descriptor']) .

>>> class DemoDescriptor:
... def __get__(self, instance, type_):
... if instance is None:
... print('Accessing descriptor on the class')
... return self
... print('Accessing descriptor on the instance')
... return 'Descriptor value for instance {!r}'.format(instance)
...
>>> class DemoClass(object):
... foo = DemoDescriptor()
...
>>> DemoClass.foo # on the class
Accessing descriptor on the class
<__main__.DemoDescriptor object at 0x1041d3c50>
>>> DemoClass.__dict__['foo'] # bypassing the descriptor protocol
<__main__.DemoDescriptor object at 0x1041d3c50>
>>> DemoClass().foo # on the instance
Accessing descriptor on the instance
'Descriptor value for instance <__main__.DemoClass object at 0x1041d3438>'

这也是 functionproperty 对象的 __get__ 方法实现的工作方式。

对于您的具体情况,Exam.math_gradeExam.writing_gradeExam.science_grade 都将调用 Grade.__get__ ,为实例传入 None,为 instance_type 传入 Exam

关于python - 为什么在描述符类的 __get__ 中需要 "if instance is None"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29436716/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com