Effective Python 读书笔记: 第31条: 用描述符来该写需要复用的@property方法

# -*- encoding: utf-8 -*-

import weakref

'''
第31条: 用描述符来该写需要复用的@property方法

关键:
1 @property
缺点: 不便于复用,受它修饰的方法无法被同一个类中其他属性复用,
与之无关的类也无法复用这些方法

2 描述符
描述符类: 可以提供__get__和__set__方法
原理: 
exam.writingGrade = 40
会被转换为
Exam.__dict__['writingGrade'].__set__(exam, 40)
获取属性会被转换为
Exam.__dict__['writingGrade'].__get__(exam, Exam)
之所以存在上述转换: 是因为object类的__getattribute__方法

类实例没有某个属性 ---> 在类中查找同名属性(
类属性,如果实现了__get__和__set__方法,则认为该对象遵循描述符协议)

3 weakref
含义:提供WeakKeyDictionary的特殊字典
特点:如果运行系统发现这种字典所持有的引用是整个程序里面执行Exam
实例的最后一份引用,那么系统就会将实例从字典的键中移除。

4 总结
1) 复用@property方法及其验证机制,用自己定义描述符类
2) WeakKeyDictionary保证描述符类不会泄露内存

参考:
Effectiv Python 编写高质量Python代码的59个有效方法
'''

# class Grade(object):
#     def __init__(self):
#         self._value = 0
#
#     def __get__(self, instance, instance_type):
#         return self._value
#
#     def __set__(self, instance, value):
#         if not (0 <= value <= 100):
#             raise ValueError('Grade must be between 0 and 100')
#         self._value = value


class Grade(object):
    def __init__(self):
        self._values = weakref.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


class Exam(object):
    mathGrade = Grade()
    writingGrade = Grade()
    scienceGrade = Grade()


def useExam():
    exam = Exam()
    exam.writingGrade = 82
    exam.scienceGrade = 99
    print exam.writingGrade
    print exam.scienceGrade
    secondExam = Exam()
    secondExam.writingGrade = 75
    print "First writing grade: {value}".format(
        value=exam.writingGrade
    )
    print "Second writing grade: {value}".format(
        value=secondExam.writingGrade
    )


def process():
    useExam()


if __name__ == "__main__":
    process() 

猜你喜欢

转载自blog.csdn.net/qingyuanluofeng/article/details/88933187