描述符和类的装饰器(三十九)

简单实现

def deco(obj):
    print("---->装饰器")
    obj.x = 1
    obj.y = 2
    obj.z = 3
    return obj

@deco
class Foo:
    pass

f = Foo()
print(Foo.__dict__)
'''
---->装饰器
{'__module__': '__main__', 
'z': 3, 'y': 2, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 
'x': 1, '__dict__': <attribute '__dict__' of 'Foo' objects>}
'''

加强版

def Typed(**kwargs):
    def deco(obj):
        for key, value in kwargs.items():
            setattr(obj, key, value)
        return obj
    return deco

@Typed(x=1, y=2, z=3)
class Foo:
    pass

@Typed(name="zhangsan")
class People:
    pass

应用:

class Typed:
    def __init__(self,key, expected_type):
        self.key = key
        self.expected_type = expected_type
    def __get__(self, instance, owner):
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        if not isinstance(value, self.expected_type):
            raise TypeError("%s is not %s" %(value, self.expected_type))
        instance.__dict__[self.key] = value
    def __delete__(self, instance):
        instance.__dict__.pop(self.key)

def deco(**kwargs):
    def wrapper(obj):
        for key, value in kwargs.items():
            setattr(obj, key, Typed(key, value))
        return obj
    return wrapper

@deco(name=str, age=int, gender=str)
class People:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

p1 = People('zhangsan', 18, 'male')
print(People.__dict__)

描述符总结

描述符是可以实现大部分python类特性中的底层魔法,包括@classmethod,@staticmethd,@property甚至是__slots__属性

描述父是很多高级库和框架的重要工具之一,描述符通常是使用到装饰器或者元类的大型框架中的一个组件.

猜你喜欢

转载自www.cnblogs.com/xiangtingshen/p/10466630.html