zoukankan      html  css  js  c++  java
  • 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)
    
  • 相关阅读:
    001_jdk配置
    mysql(5.7)安装教程
    mysql(5.6)安装教程
    外网发布
    蓝桥 历届试题 分考场
    蓝桥 历届试题 合根植物
    Codeforces Round #650 (Div. 3) D : Task On The Board
    HDU 3336 Count the string
    leetcode [238. 除自身以外数组的乘积]
    leetcode [837. 新21点]
  • 原文地址:https://www.cnblogs.com/jia-shu/p/14176269.html
Copyright © 2011-2022 走看看