Python - 装饰器及有参

装饰器

初始

开放封闭原则:

扩展是开放的(增加新功能)

修改源码是封闭(修改已经实现的功能)

在不改变源代码及调用方式的基础下额外增加新的功能

装饰器:用来装饰的工具
 标准版(装饰器):
 def func(a):  #a是要被装饰的函数名
     def foo(*args,**kwargs):
         "装饰之前的操作"
         ret = a(*args,**kwargs)
         "装饰之后的操作"
         return ret
     return foo
 @func
 def f1(*args,**kwargs):
     print(f"这是一个{args}")
     return "我可以返回了"
 f1(1,2,3,34,4,5)
 语法糖 -- 甜
 语法糖必须放在被装饰的函数正上方

有参装饰器

 带参数的装饰器

def startEnd(fun):
    def wraper(name):
        print("!!!!!!!!!!!!start!!!!!!!!!")
        fun(name)
        print("!!!!!!!!!!!!!end!!!!!!!!!")
    return wraper
 返回值是wraper函数
 hello()相当于执行wraper()

@startEnd
def hello(name):
    print("hello {0}".format(name))

hello("boy")


 在不改变代码的情况下,给现有的函数增加新的功能
 装饰器通过@进行使用,相当于把hello()函数作为参数
 @startEnd  相当于  hello = startEnd(hello())
 当调用hello()的时候,就相当于调用了startEnd(hello())

 装饰器其实就是要你的内存地址
 重新给你封装新的内存 地址。
 你执行的时候是执行新的内存地址

 a = hello
 a() 相当于hello()
 a = startEnd(hello)
 a = hello   核心

def author(mm):
    def hello(fun):
        def preHello(name):
            print("This author is {0}".format(mm))
            print("###########start################")
            fun(name)
            print("############end#################")
        return preHello
    return hello

@author("aaa")       #装饰器最外面的一个传入的参数
def cs(name):        #装饰器传入的函数,中间那个
    print("welcome  {0}".format(name))

 xx = author("chen")(cs)
 xx("aaaavvvvv")
cs("ffffffff")      #装饰器最里面传入的

多个装饰器装饰一个函数

def wrapper1(func):
    def inner1(*args,**kwargs):
        print(1)
        func(*args,**kwargs)
        print(11)
    return inner1

def wrapper2(func):  # func == foo
    def inner2(*args,**kwargs):
        func(*args, **kwargs)
        print(22)
    return inner2

def wrapper3(func):
    def inner3(*args,**kwargs):
        print(3)
        func(*args, **kwargs)
        print(33)
    return inner3

 @wrapper1  # 1 11
 @wrapper3  # 3 33
 @wrapper2  #  8 22

 def foo():
     print(8)

 foo = wrapper2(foo)  # foo == inner2
 foo = wrapper3(foo)  # inner3 = wrapper3(inner2)
 foo = wrapper1(foo)  # inner1 = wrapper1(inner3)
 foo()                # inner1()


 foo = wrapper3(foo)  # foo == inner3
 foo = wrapper2(foo)  # foo = wrapper2(inner3)  foo == inner2
 foo = wrapper1(foo)  # foo = wrapper1(inner2)


 被装饰的函数正上方有多个装饰器,先执行离被装饰函数最近的装饰器

 先执行离被装饰的函数最近的语法糖
 小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走
posted @ 2019-09-28 18:13  赵刚、  阅读(156)  评论(0编辑  收藏  举报