十九.面向对装饰器

一  装饰器

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

 

posted @ 2019-06-26 15:14  supreme9999  阅读(156)  评论(0编辑  收藏  举报