19 描述符应用 与类的装饰器

上下文管理协议

class Open:
    def __init__(self,name):
        self.name = name
    def __enter__(self):
        print('执行enter')
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('执行exit')
with Open('a.txt') as f:
print(f)
print('______')
print('00000')

with open 执行了enter f为enter返回值
with open结束调用exit
如果遇到异常也调用exit exit返回值为True 结束with open继续运行
为False 程序崩掉

描述符本身应该定义为新式类 被代理的类也应该是新式类
必须把描述符定义成类属性 不能定义到构造函数中
严格遵守优先级:类属性 数据描述符 实例属性 非数据描述符 找不到
描述符应用:

class Typed:
    def __get__(self, instance, owner):
        print('get method')
        print('instance 参数 %s'%instance)
        print('owner data %s'%owner)
    def __set__(self, instance, value):
        print('set methhod')
        print('instance 参数 %s' % instance)
        print('value data %s' % value)
class People:
    name = Typed()
    def __init__(self,name,age,salary):
        self.name = name
        self.age = age
        self. salary = salary
p1 = People('AAA',19,30.8)
# p1.name = 'BBB'
# print(p1.__dict__)
# p1.name

上例++

class Typed:
    def __init__(self,key):
        self.key = key
    def __get__(self, instance, owner):
        print('get method')
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print('set methhod')
        if type(value) == str:
            pass
        else:
            return
            instance.__dict__[self.key] = value
    def __delete__(self, instance):
        print('delete method')
        instance.__dict__.pop(self.key)
class People:
    name = Typed('name')
    def __init__(self,name,age,salary):
        self.name = name
        self.age = age
        self. salary = salary
p1 = People('AAA',19,30.8)
p1.name = 'BBB'
# print(p1.__dict__)
del p1.name

类的装饰器的基本原理

def deco(obj):
    print('+++++++',obj)
    obj.x = 1
    return obj
@deco
class Foo:
    pass
print(Foo.__dict__)

增强版

def Typed(**kwargs):
    def deco(obj):
        # print('---------->',kwargs)
        # print('类名++++',obj)
        # obj.x = 1
        for key,val in kwargs.items():
        setattr(obj,key,val)
        return obj
        print('=====>>',kwargs)
    return deco
@Typed(x=1,y = 2,z = 3)
class Foo:
    pass
print(Foo.__dict__)


进阶版++ 可增加属性 略
自定制属性

class Lazy:
    def __init__(self,func):
        print('======>')
        self.func = func
    def __get__(self, instance, owner):
        print('get')
        print(instance)
        print(owner)
val = self.func(instance)
return val

class Room:
    x = property('x')
    def __init__(self,name,width,length):
        self.name = name
        self.width = width
        self.length = length
# @property #area = property(area)
@Lazy
    def area(self):
        return self.width * self.length
r = Room('厕所',3,10)
print(r.area)
# print(Room.__dict__)

元类
元类是类的类 是类的模板
元类的实例为类 正如类的实例是对象
type是python中的一个内建元类 用来直接生成类

自定义元类

class MyType(type):
    def __init__(self,a,b,c):
        print('元类的构造函数执行')
    def __call__(self, *args, **kwargs):
        obj = object.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj
class Foo(metaclass = MyType): #foo(none) = mytype(foo,'foo,(),            {}---> __init__
    def __init__(self,name):
        self.name = name
f1 = Foo('alex')
原文地址:https://www.cnblogs.com/louzhiyuan/p/10461851.html