6

次の例は、有効な Python 項目 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')

if instance is None: return self入れる理由が思いつきません__get__Exam(または を使用する他の潜在的なクラスGrade) インスタンスはどのようになりNoneますか?

4

1 に答える 1

7

Python はNone、クラスの記述子にアクセスするときにインスタンスを渡します。

selfその場合に戻ることにより、プロトコルをバイパスする必要なく ( にアクセスして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>'

これは、およびオブジェクトの__get__メソッド実装もどのように機能するかです。functionproperty

あなたの特定のケースではExam.math_gradeExam.writing_gradeまたはのそれぞれがExam.science_gradeを呼び出し、インスタンスGrade.__get__を渡し、.NoneExaminstance_type

于 2015-04-03T17:17:04.677 に答える