欢迎来到十九分快乐的博客

生死看淡,不服就干。

6.装饰器

装饰器

定义:装饰器用于扩展原来函数功能的一种语法,返回新函数替换就函数
优点 :在不改变原函数代码的前提下,给函数扩展新的功能

1.装饰器原型

def kuozhan(func): #闭包函数
    def newfunc():
        print(1111)
        func()
        print(2222)
    return newfunc

def func():
    print("我要飞的更高")
    
func = kuozhan(func)
func()

2.@语法糖的使用

"""
@的两个作用:
    1. 自动把@装饰器下面的函数当成参数传递给装饰器
    2. 将装饰器返回到新函数替换旧函数,完成功能扩展
"""
def kuozhan(func):
    def newfunc():
        print("aa")
        func()
        print("bb")
    return newfunc

@kuozhan
def func():
    print("遇事不要慌~")
    
func()

3.装饰器的嵌套

def kuozhan1(func):
    def newfunc():
        print(11)
        func()
        print(22)
    return newfunc
    
def kuozhan2(func):
    def newfunc():
        print("aa")
        func()
        print("bb")
    return newfunc
#从下到上,层层嵌套    
@kuozhan1
@kuozhan2
def func():
    print("好好学习,天天向上")

func()

4.带有参数的装饰器

"""
原函数有几个参数,新函数就有几个参数
"""
def kuozhan(func):
    def newfunc(who,where):#替换的新函数
        print(666)
        func(who,where)
        print(888)
    return newfunc
    
@kuozhan    
def func(who,where): #原函数
    print("{}在{}".format(who,where))
    
func("贾英贺","学校")

5.带有参数返回值的装饰器

"""
参数和返回值与原函数保持一致
"""
def kuozhan(func):
    def newfunc(*args,**kwargs):#定义处打包成元组,字典
        print("床前明月光")
        res = func(*args,**kwargs)#调用处解包
        print("地上鞋两双")
        return res
    return newfunc
@kuozhan        
def func(*args,**kwargs):
    strvar = ""
    lst = []
    dic = {"ss":"贾英贺","xd":"熊大"}
    try: #防止报错
        i = 0
        for k,v in kwargs.items():
            if k =="ss":
                strvar = dic[k] + "玩坏{}个{}".format(v,args[i])
            elif k == "xd":
                strvar = dic[k] + "玩坏{}个{}".format(v,args[i])
            else:
                strvar = "没有这个人"
            lst.append(strvar)
            i +=1
    except:
        print("数据没找到")
        lst.append("数据没找到")
    return lst

res = func("足球","篮球",xd = 3,ss = 5, jyh = 2)
print(res)

6.类装饰器

class KuoZhan():
    def kuozhan1(func):
        def newfunc():
            print("111")
            func()
            print("222")
        return newfunc
    def kuozhan2(self,func):
        def newfunc():
            print("aaa")
            func()
            print("bbb")
        return newfunc
    def __call__(self,func):
        return self.kuozhan2(func)

# 方法一:
@KuoZhan.kuozhan1 #使用类本身调用函数
def func():
    print("我是单身狗~!")
func()
# 方法二
@KuoZhan() #把对象当成函数调用,自动触发魔术方法__call__ (推荐使用)
def func():
    print("谁还不是的孩子")
func()

7.带有参数函数的装饰器

def outer(num):
    def kuozhan(func):
        def newfunc1(self):
            print(111)
            func(self)
            print(222)
        def newfunc2(self):
            print(333)
            func(self)
            print(444)
        if num ==1:
            return newfunc1
        elif num ==2:
            return newfunc2
        elif num == 3:
            return "哈哈哈哈" #把原函数方法变成成员属性
    return kuozhan

class My():
    @outer(1) #@kuozhan=>func = kuozhan(func)
    def func1(self):
        print("aaaaaa")
    @outer(2)
    def func2(self):
        print("bbbb")
    @outer(3)
    def func3(self):
        print("ccccc")

obj = My()
obj.func1()
obj.func2()
print(obj.func3)

8.带有参数类的装饰器

"""
1.当参数为1时,为My类添加成员属性和方法
2.当参数为2时,把My类中的run方法变成属性
"""
class Kuo():
    ad = 12345
    def func(self):
        print("小屌丝一个")
    def __init__(self,num): #实例化对象触发
        self.num = num
    def __call__(self,cls): #把对象当函数使用时触发
        if self.num ==1:
            return self.kuozhan1(cls)
        elif self.num == 2:
            return self.kuozhan2(cls)
    def kuozhan1(self,cls):
        def newfunc():
            cls.ad = self.ad #为cls类添加成员属性
            cls.func = self.func #为cls类添加成员方法
            return cls() #返回cls类对象
        return newfunc
    def kuozhan2(self,cls):
        def newfunc():
            if "run" in cls.__dict__: #判断类中是否有run成员
                cls.run = cls.run(cls()) #把cls类中方法变成属性
            return cls() #返回cls类对象
        return newfunc

#@obj =>My = obj(My) 触发__call__返回kuozhan1 =>返回newfunc
#所以My = newfunc
#再调用My() 返回My类对象
@Kuo(1) 
class My():
    def run(self):
        print("啥也不是")

obj  =My()
obj.func()
print(obj.ad)

@Kuo(2)
class My():
    def run(self):
        return "我是run~~!"

obj = My()
print(obj.run)
posted @ 2020-12-22 23:57  十九分快乐  阅读(31)  评论(0编辑  收藏  举报