风火编程--with管理多个上下文, 描述符

《流畅的python》读书笔记(十)

19.1 动态属性
with 可以同时管理多个上下文.

def rewrite():
    """读写文件a->b"""
    with open("a.txt", "r") as fr, open("b.txt", "w") as fw:
        data = fr.readline()
        while data:
            print(data)
            fw.writelines(data)
            data = fr.readline()

if __name__ == '__main__':
    rewrite()

19.6 获取实例属性
定义了__slots__属性的实例不能使用vars(), 可以使用dir()查看实例的属性字典.

尝试获取属性时会先调用__get_attribute__(),发生AttrbuteError后再调用__get_attr__().

20.1 描述符
实现了描述符协议: get, set, __delete__方法中的一个或多个的类, 对多个属性使用相同的逻辑进行操作.
创建描述符的一个实例作为其他类的类属性, 在进行初始化的时候定义同名的实例属性就会遵守描述符的约束.

通过instance.dict[“attr_name_str”]可以通过属性名的字符串获取到instance的属性

class Quantity:
    """自然量的描述符"""
    __counter = 0
    def __init__(self):
        cls = self.__class__
        prefix = cls.__name__
        index = cls.__counter
        self.storage_name = '_{}#{}'.format(prefix, index)
        cls.__counter += 1

    def __get__(self, instance, owner):
        if instance is None:
            return self
        else:
            return getattr(instance, self.storage_name)

    def __set__(self, instance, value):
        if value > 0:
            setattr(instance, self.storage_name, value)
        else:
            raise ValueError("value must > 0")

def entity(cls):
    """修改描述符storage_name的类装饰器"""
    for key, attr in cls.__dict__.items():
        if isinstance(attr, Quantity):
            attr.storage_name = "_Quantity#{}".format(key)
    return cls

@entity
class Goods:
    """商品类"""
    price = Quantity()
    def __init__(self, price):
        self.price = price

if __name__ == '__main__':
    g1 = Goods(50)
    print(g1.price)
    print(vars(g1))
    # g2 = Goods(-50)

raise Error(“discraption”) 中的discraption不能用格式化

没有实现__set__()的是非覆盖型描述符, 如果哦通过实例设置同名属性, 描述符会被覆盖.

21.1 eval和exec不能用于处理存在风险的字符串.
21.4 创建只读属性应使用特性.
类的定义体属于顶层代码, 会在导入时执行.

type是其自身的实例.

标准库中的元类: ABCMeta, Enum

21.7 类作为对象
类的基类元组: cls.bases

类的超类元组: cls.mro(), mro

属性: dict, vars(instance), dir(instance)

你可能感兴趣的:(with,上下文,查看实例属性,描述符,python)