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)