from weakref import WeakKeyDictionary
class Grade(object):
def __init__(self):
self._values = WeakKeyDictionary()
# 用字典来记录每个实例的状态。
# 为了避免实例引用计数无法降为0,
# 垃圾回收器无法回收,这里用弱引用字典。
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
class Exam(object):
math = Grade()
english = Grade()
exam = Exam()
exam.math = 97 # Exam.__dict__['math'].__set__(exam, 40)
exam.english = 89
print(exam.math) # Exam.__dict__['math'].__get__(exam, Exam)
print(exam.english)
exam.english = 87
print(exam.english)
# 97
# 89
# 87