• 十九.面向对装饰器


    一  装饰器

    def decorate(cls):
        print('类的装饰器开始运行啦------>')
        return cls
    
    @decorate #无参:People=decorate(People)
    class People:
        def __init__(self,name,age,salary):
            self.name=name
            self.age=age
            self.salary=salary
    
    p1=People('egon',18,3333.3)
    
    类的装饰器:无参
    def Super(**kwargs):
        def inner(obj):
            for key,val in  kwargs.items():
                print(key,val,"这是传过来的参数")
                setattr(obj,key,val)
            return  obj
        return  inner
    
    
    @Super(a=1,b=2)            #  Foo=super(Foo)
    class Foo(object):
        pass
    print(Foo.__dict__)
    
    # a 1 这是传过来的参数
    # b 2 这是传过来的参数
    # {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'a': 1, 'b': 2}
    def typeassert(**kwargs):
        def decorate(cls):
            print('类的装饰器开始运行啦------>',kwargs)
            return cls
        return decorate
    @typeassert(name=str,age=int,salary=float) #有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
    class People:
        def __init__(self,name,age,salary):
            self.name=name
            self.age=age
            self.salary=salary
    
    p1=People('egon',18,3333.3)
    
    # 类的装饰器开始运行啦------> {'name': <class 'str'>, 'age': <class 'int'>, 'salary': <class 'float'>}
    from functools import wraps
    def wrapper(func):
        @wraps(func)
        def inner(self,*args,**kwargs):
            # 此时的self是Person的实例对象
            self.name += "爱吃糖11111111111111111111111"
            # func ===>  printInfo
            ret = func(self,*args,**kwargs)
            return ret
        return inner
    
    class Person(object):
        def __init__(self,name):
            self.name = name
        @wrapper     #printInfo=wrapper(printInfo)
        def printInfo(self):
            print(self.name)
    
    # printInfo ==> wraper(printInfo) ==> inner
    aa=Person("张三")
    aa.printInfo()
    # 张三爱吃糖11111111111111111111111

    装饰器描述符来实现 实例化参数类型判断

    class Typed:
        def __init__(self,name,expected_type):
            self.name=name
            self.expected_type=expected_type
        def __get__(self, instance, owner):
            if instance is None:
                return self
            return instance.__dict__[self.name]
    
        def __set__(self, instance, value):
            if not isinstance(value,self.expected_type):
                raise TypeError('Expected %s' %str(self.expected_type))
            instance.__dict__[self.name]=value
    
        def __delete__(self, instance):
            instance.__dict__.pop(self.name)
    
    def typeassert(**kwargs):
        def decorate(cls):
            for name,expected_type in kwargs.items():
                setattr(cls,name,Typed(name,expected_type))
            return cls
        return decorate
    @typeassert(name=str,age=int,salary=float) #有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
    class People:
        def __init__(self,name,age,salary):
            self.name=name
            self.age=age
            self.salary=salary
    
    print(People.__dict__)
    p1=People('egon',18,3333.3)
    def fun(obj):
        obj.x=1
        obj.y= 2888
        return  obj
    @fun  #  ====>>> Foo=fun(Foo)
    class Foo(object):
        pass
    print(Foo.__dict__)

    装饰器 functools.wraps

    def auth(func):
        def inner(*args,**kwargs):
            print("")
            ret = func(*args,**kwargs)
            print("")
            return ret
        return inner
    
    @auth
    def index():
        print('index')
    index()
    
    @auth
    def detail():
        print('detail')
    detail()
    
    print(index.__name__)   #打印的函数名    inner
    print(detail.__name__)  #打印的函数名    inner
    # 执行结果:
            #
            # index
            #
            #
            # detail
            #
            # inner
            # inner
    # functools.wraps的特点:
    #
    # 被装饰函数不受装饰器的影响
    # 装饰器的名字变成被装饰名字,外部调用到的被装饰函数的功能
    # 1. 装饰器
    import functools
    def auth(func):
        @functools.wraps(func)    # 加上这装饰器会把原来的函数所有信息放入 inner中 伪装的更彻底      但是打印的就会变成被装饰的函数名
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)
            return ret
        return inner
    
    @auth
    def index():
        print('index')
    
    
    @auth
    def detail():
        print('detail')
    
    print(index.__name__) # index
    print(detail.__name__)  # detail

    二、类装饰器实现单例模式

    def wrapper(obj):
        def inner(name,*args,**kwrags):
            if not obj.instance:
                obj.instance = obj(name)
            return obj.instance
        return inner
    
    @wrapper                          >>>>> Person=wrapper(Person)
    class Person(object):
        instance = None
        def __init__(self,name):
            self.name = name
    
        def printInfo(self):
            print(self.name)
    
    zs = Person('张三')
    zs.printInfo()
    print(id(zs))
    
    ls = Person('李四')
    ls.printInfo()
    print(id(ls))



    张三
    2514106528432
    张三
    2514106528432

  • 相关阅读:
    Mac下java环境jdk、maven环境安装
    Pandas基本操作
    python-numpy入门
    深度学习-Pytorch基础
    深度学习-手写数字识别代码
    机器学习-梯度下降算法案例
    机器学习-EM算法
    机器学习-特征选择
    机器学习-聚类
    机器学习-朴素贝叶斯
  • 原文地址:https://www.cnblogs.com/Sup-to/p/11090017.html
Copyright © 2020-2023  润新知