zoukankan      html  css  js  c++  java
  • python 装饰器 对类和函数的装饰

    #装饰器:对类或者函数进行功能的扩展  很多需要缩进的没有进行缩进
    '''
    #第一步:基本函数
    def laxi():
    print('拉屎')
    #调用函数
    laxi()
    laxi()

    print('=======================================')
    #第二步:扩展函数的功能(不能修改原函数)
    #用于扩展基本函数的函数
    #把一个函数(laxi函数)作为一个整体传给另外一个函数(kuozhan函数)
    #这个函数(kuozhan函数)用形参func收到了laxi函数,收到之后在中间
    #调用laxi函数,并且在前面后面扩展功能
    def kuozhan(func):
    #扩展功能1
    print('拉屎之前')
    #调用基本函数
    func()
    #扩展功能2
    print('拉屎之后')
    #这里需要有返回值才能传给laxi
    #基本函数
    def laxi():
    print('拉屎')

    #扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
    laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    print(laxi)

    #调用函数
    #laxi()

    print('=======================================')
    #第三步:使用语法糖(就是语法)
    #用于扩展基本函数的函数
    def kuozhan(func):
    #扩展功能1
    print('拉屎之前')
    #调用基本函数
    func()
    #扩展功能2
    print('拉屎之后')
    #这里需要有返回值才能传给laxi
    #基本函数
    @kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    def laxi():
    print('拉屎')
    #扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
    #laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    print(laxi)

    #调用函数
    #laxi()

    print('=======================================')
    #第四步:基本装饰器的实现
    #用于扩展基本函数的函数
    def kuozhan(func):
    #内部函数(扩展之后的laxi函数)
    def newlaxi():
    #以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
    #取名叫做newlaxi
    #扩展功能1
    print('拉屎之前')
    #调用基本函数
    func()
    #扩展功能2
    print('拉屎之后')
    #这里需要有返回值才能传给laxi
    #添加返回值
    #return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
    #所以return后面必须是扩展之后的函数
    return newlaxi
    #基本函数
    @kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    def laxi():
    print('拉屎')
    #扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
    #laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
    #而不是像第二步和第三步打印回来的是None
    #调用函数
    laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值

    print('=======================================')
    #第五步:带有参数的装饰器
    #用于扩展基本函数的函数
    def kuozhan(func):
    #内部函数(扩展之后的laxi函数)
    #5由于调用的时候传了两个参数,未来的laxi函数没有参数接收
    #5报错的时候显示newlaxi没有形参接收,但是给了两个实参
    #5所以需要添加两个形参接收shui,na
    def newlaxi(shui,na):#5调用的杨羊传到了shui,na
    #4以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
    #4取名叫做newlaxi
    #扩展功能1
    print('拉屎之前')
    #调用基本函数
    func(shui,na)#5上面的shui,na传到了这里的shui,na
    #扩展功能2
    print('拉屎之后')
    #4这里需要有返回值才能传给laxi
    #添加返回值
    #4return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
    #4所以return后面必须是扩展之后的函数
    return newlaxi
    #基本函数
    @kuozhan#laxi = kuozhan(laxi) #4laxi就相当于以前的result,用来接收返回值
    def laxi(who,where):#5上面的func的shui,na传到了这里的who,where
    print(who,'在',where,'拉屎')
    print('拉屎')
    #扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
    #laxi = kuozhan(laxi) #4laxi就相当于以前的result,用来接收返回值
    #print(laxi)#4第四步的目的是为了让打印laxi函数的时候打印一个函数
    #4而不是像第二步和第三步打印回来的是None
    #调用函数
    laxi('杨俊','羊圈')#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
    laxi('燕飞','鸟窝')

    print('=======================================')
    def laxi():
    print('拉屎')
    return '擦屁股'
    #扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
    #laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
    #而不是像第二步和第三步打印回来的是None
    #调用函数
    result = laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
    print(result)# 调用和返回值都打印出来了
    print('=======================================')
    #第五步:带有返回值的装饰器 把第四步复制过来
    #用于扩展基本函数的函数
    def kuozhan(func):
    #内部函数(扩展之后的laxi函数)
    def newlaxi():
    #以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
    #取名叫做newlaxi
    #扩展功能1
    print('拉屎之前')
    #调用基本函数
    result1 = func()
    #扩展功能2
    print('拉屎之后')

    #未来的laxi函数没有返回值,所以在最后调用的时候返回值为None
    #为newlaxi添加返回值
    return result1

    #这里需要有返回值才能传给laxi
    #添加返回值
    #return 12 laxi原来是函数,laxi扩展之后还以函数的形式赋值给laxi
    #所以return后面必须是扩展之后的函数
    #5装饰器用于返回未来的laxi函数的return
    #5而不是newlaxi(laxi)自带的返回值
    #5应该在newlaxi函数里面再加一个return
    return newlaxi
    #基本函数
    @kuozhan#laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    def laxi():
    print('拉屎')
    return '擦屁股'
    #扩展之后的函数要重新赋值给基本函数!(但是此步骤还实现不了)
    #laxi = kuozhan(laxi) #laxi就相当于以前的result,用来接收返回值
    #print(laxi)#第四步的目的是为了让打印laxi函数的时候打印一个函数
    #而不是像第二步和第三步打印回来的是None
    #调用函数
    result = laxi()#laxi就是扩展的内部函数newlaxi函数,就是return返回的值
    print('函数的返回值为',result)
    print('=======================================')

    #第六步:带有收集参数的函数的装饰器
    #装饰器函数
    def kuozhan(func):
    #内部函数(扩展之后的laxi函数)
    def newlaxi(*w,**n):
    #以下三步就是扩展之后的功能,于是我们把这三个哥们做成一个函数
    #取名叫做newlaxi
    #扩展功能1
    print('拉屎之前')
    #调用基本函数
    func(*w,**n)
    #扩展功能2
    print('拉屎之后')
    return newlaxi
    #基本函数
    @kuozhan
    def laxi(*who,**nums):
    print('参与拉屎的有',who)
    print('他们分别拉了多少屎',nums)
    print('拉屎')

    #调用函数,'
    laxi('许钰','王成','秀峰','张波',xy = '15斤',wc = '15吨',xf = '15克',zb = '15升')

    print('=======================================')

    #第七步:带有参数的装饰器
    #两个基本函数用同一个装饰器装饰
    def outer(arg):
    print(arg)
    #这是装饰器的代码
    def kuozhan(func):
    #print(func) func接收的不再是laxi,而是la,chi
    #未来的laxi函数
    def newlaxi():
    # 扩展功能1
    print('拉屎之前')
    # 调用基本函数
    func()
    # 扩展功能2
    print('拉屎之后')

    def newchifan():
    # 扩展功能1
    print('吃饭之前')
    # 调用基本函数
    func()
    # 扩展功能2
    print('吃饭之后')

    if arg == 'la':
    return newlaxi
    elif arg == 'chi':
    return newchifan

    #返回装饰器
    return kuozhan
    #基本函数1
    result = outer('la')
    @result #@装饰器函数
    def laxi():
    print('拉屎')

    #基本函数2
    @outer('chi')
    def chifan():
    print('吃饭')

    #调用基本函数
    #laxi()
    chifan()

    print('==============================================')
    #第八步:使用类作为装饰器参数
    #装饰器使用的操作类
    class Wish:
    #祈求方法
    def before():
    print('拉屎之前')
    #还愿方法
    def after():
    print('拉屎之后')
    #装饰器函数
    def outer(cls):
    def kuozhan(func):
    # 未来的laxi函数
    def newlaxi():
    # 扩展1(类中存在扩展内容)
    cls.before()
    # 调用基本函数
    func()
    # 扩展2(类中存在扩展内容)
    cls.after()

    return newlaxi

    return kuozhan

    #基本函数
    @outer(Wish)#装饰器
    def laxi():
    print('拉屎')

    #调用函数
    laxi()

    print('==============================================')
    #第九步:使用类来作为装饰器


    class kuozhan:

    #接收装饰器的参数(函数outer)
    def __init__(self,arg):
    #print(self,arg)arg就是la
    self.arg = arg

    #制作一个内部函数(真正的装饰器 函数kuozhan)
    def __call__(self,func):
    #print(self,func)func就是laxi函数
    #将func函数存入对象
    self.func = func

    return self.newlaxi
    #在面向对象过程当中不提倡内使用内部函数,要提到前面
    #定义称为一个成员方法
    def newlaxi(self):
    # 扩展功能1
    print('拉屎之前')
    # 调用基本函数
    self.func()
    # 扩展功能2
    print('拉屎之后')

    #基本函数
    @kuozhan('la')# laxi = 对象(laxi)
    def laxi():
    print('拉屎')

    #调用函数
    laxi()

    print('==============================================')
    #第十步:装饰器来装饰一个类
    def kuozhan(cls):
    #print(cls)

    #声明一个类并且返回
    def newHuman():
    # 扩展类的功能1
    cls.cloth = '漂亮的小裙子'
    # 扩展类的功能2
    cls.hat = '亮丽的绿帽子'
    #调用类(实例化对象)
    obj = cls()
    #返回实例化对象
    return obj
    return newHuman #要让返回的newHuman也能实例化对象
    #类(被装饰的类)
    @kuozhan #Human = kuozhan(Human) = newHuman
    #最后调用的Human()= newHuman()= obj = cls()= 扩展后的Human()
    class Human:
    #属性
    sex = '男'
    age = 18

    #方法
    def liaomei(self):
    print('妹子,这块砖头是你掉的吗')

    #实例化对象
    result = Human()
    print(result)
    print(result.__dict__)
    print(result.cloth)
    print(result.hat)
    print('===================================================')
    #函数的调用
    def laxi():
    print('拉屎')
    return '撒尿'
    result = laxi()
    print(result)
    '''
    print('===================================================')
    #第十一步:多层装饰器的嵌套

    #装饰器1
    def kuozhan1(func):
    #定义装饰之后的函数
    def newlaxi1():
    # 扩展功能1
    print('1-----拉屎之前')
    # 调用基本函数
    func()
    # 扩展功能2
    print('1-----拉屎之后')
    return newlaxi1

    #装饰器2
    def kuozhan2(func):
    #定义装饰之后的函数
    def newlaxi2():
    # 扩展功能1
    print('2-----拉屎之前')
    # 调用基本函数
    func()
    # 扩展功能2
    print('2-----拉屎之后')
    return newlaxi2

    #基本函数
    @kuozhan2
    @kuozhan1
    def laxi():
    print('拉屎')

    #调用函数
    laxi()

  • 相关阅读:
    集合总结(非常重要)
    day18_Map案例
    Map代码案例
    重踏学习Java路上_Day18(Map,Collections)
    TreeSet概述(源码和内部图 进行解析,包含练习案例)
    HashSet保证元素唯一性的代码体现(源码和内部图 进行解析)
    重踏学习Java路上_Day17(登录注册案例,Set集合,Collection集合总结,在集合中常见的数据结构)
    Java 泛型解析,太难了,认真读才能理解
    题解 【BZOJ4700】适者
    题解 楼房重建
  • 原文地址:https://www.cnblogs.com/zhangboblogs/p/7860850.html
Copyright © 2011-2022 走看看