美文网首页
9.描述符 装饰器

9.描述符 装饰器

作者: 芝麻酱的简书 | 来源:发表于2018-08-21 14:15 被阅读4次

描述符:

描述符本质是一个新式类,在这个新式类中,至少出现了__get__()__set__()或者__delete__()方法中的一个,也被称为描述符协议。

  • __get__()obj.name调用一个属性的时候触发
  • __set__()obj.name = "bill"为一个属性赋值的时候触发
  • __delete__()del obj.name采用del删除属性的时候,触发

描述符分为两种:

  • 数据描述符 至少实现了__get__()__set__()
  • 非数据描述符 没有实现__set__()

注意:对象本身调用不会触发描述符协议,当该新式类为别的类的属性,通过别的类来调用该新式类时候才会触发“

class Foo:
    def __set__(self, instance, value):
    # 可以通过__dict__属性字典设置,在设置前可以增加判断等操作
 
        print("hahaha")


class Tmp:
    #Foo()是数据描述符 代理了foo对象的属性调用相关方法
    foo = Foo()

result = Tmp()
result.foo = "asdf"

函数装饰器复习

前有函数装饰器:

def foo(func):
    print("装饰器")
    return func;

@foo   # 这一步就等于func1 = foo(func1)
def func1():
    print("func1")


func1()

类装饰器使用

终极代码:类装饰器 + 描述符

class TypedC:
    def __init__(self, key, classType):
        self.key = key
        self.classType = classType

    def __get__(self, instance, owner):
        return instance.__dict__[self.key]

    def __set__(self, instance, value):
        if not isinstance(value, self.classType):
            raise TypeError("传入的数据类型有问题")
        instance.__dict__[self.key] = value


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


@out_deco(name=str, age=int)
class New:

    def __init__(self, name, age):
        self.name = name
        self.age = age



print(New("alex",100).__dict__)

解释:

@out_deco(name=str, age=int)
先忽略@,即执行右半边方法: out_deco(name=str, age=int)  -> out_deco({字典}) 
得到:
@in_deco(New)   相当于   New = in_deco(New)

然后执行in_deco(New)内部循环:
setattr(obj, key, TypedC(key,value))  相当于  New.key = TypedC("name", str)




自定义装饰器

使用类装饰器 模拟系统@property的实现

class Deco_class:
    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return self.func(instance)


class Foo:
    def __init__(self):
        pass

    @Deco_class
    def showAnim(self):
        print("show anim 运行")

obj = Foo()
obj.showAnim

改进版:储存函数执行结果,下次不用重复计算执行

class Deco_class:
    def __init__(self, func):
        self.func = func

    # 因为没有重写__set__方法,所以是非数据描述符,优先级比实例属性低
    def __get__(self, instance, owner):

        res = self.func(instance)
        # 储存结果到实例对象中后 下次调用 由于优先级的问题  会优先从实例对象中查找showAnim方法,而不是调用非数据描述符
        setattr(instance, self.func.__name__, res)
        return res


class Foo:
    def __init__(self):
        pass

    @Deco_class
    def showAnim(self):
        print("show anim 运行")

obj = Foo()
obj.showAnim


补充:

使用@property装饰器修饰的方法,不可以赋值,需要:

class Foo:

    @property
    def showAnim(self):
        print("show anim 运行")

    @showAnim.setter
    def showAnim(self, name):
        print("show anim 运行", name)

obj = Foo()
obj.showAnim

obj.showAnim = "bill"

另一种写法:

class Foo:

    def get_a(self):
        print("get method")

    def set_a(self, val):
        print("set method")

    def del_a(self):
        print("del method")

    aaa = property(get_a, set_a, del_a)

obj = Foo()
obj.aaa = "bill"

相关文章

  • 9.描述符 装饰器

    描述符: 描述符本质是一个新式类,在这个新式类中,至少出现了__get__()、__set__()或者__dele...

  • TypeScript——装饰器(三)

    访问器装饰器 访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。 访问器装饰器应用于访问器的 属性描述符...

  • 聊一聊python中的黑魔法之各种xxx器

    python中有装饰器、生成器、描述器、迭代器,description这个单词在很多资料里被翻译成描述符符,翻译的...

  • Nest.js - 自定义路由参数装饰器

    ES2016的装饰器是一个可以将目标对象,名称和属性描述符作为参数的返回函数的表达式。 可通过装饰器前缀@使用,放...

  • Python装饰器13-对象属性查找策略

    在进入使用类作为装饰器函数时,需要熟悉Python的描述符以及Python寻找属性查找策略。 使用dir查看Pyt...

  • python语法 -- 描述符与装饰器

    描述符 描述符是一种属性托管的方法,一个类只要实现了__get__、__set__、__del__(未必全部实现)...

  • Python 描述符对象 Descriptor Objects

    Reproduce from python描述符(descriptor)、属性(Property)、函数(类)装饰...

  • python元类编程(1)

    1. property动态属性 @property装饰器可以把一个类函数变成一个属性描述符, 能够像访问类的属性一...

  • 9. 装饰器和闭包

    [TOC] 装饰器 闭包函数 思考练习 要计算这段代码的结果,首先需要具备“python中一切皆对象”的思想。在p...

  • 装饰器

    """@装饰器- 普通装饰器- 带参数的装饰器- 通用装饰器- 装饰器装饰类- 内置装饰器- 缓存装饰器- 类实现...

网友评论

      本文标题:9.描述符 装饰器

      本文链接:https://www.haomeiwen.com/subject/tesdiftx.html