装饰器功能强大,如何运行呢,本文以函数装饰器来说明下
1、定义
def wrap(f):
return f #此处返回函数
@wrap
def
func(a:int,b:str):
pass
注意和@wrap ()比较,后面这个形式是装饰器本身传参数时候用。实际是wrap()(func)()多层而已
后面详解。
2、调用
func(a:int,b:str)
调用时候发生了什么?
首先调用wrap 返回一个函数(注意,函数类装饰器,必须最终返回函数)
在调用返回的函数。 可理解为:wrap(func)(2,"ff")
所以最终调用还是按照原被装饰函数形式进行,比如参数限制。
上面装饰器很简单,限制了参数,若写个灵活的,可装饰任意函数(带任意参数的,变参形式)如何?
一般因为被装饰函数参数固定,如何不固定呢?想到了 args kwargs
也就是重写个函数改变原先调用时候规定参数的限制。如下
-
def wrap2(f):
-
def iner(*args,**kwargs): #用args kwargs,iner函数替换原先函数的固定参数约定,可接受任意形式参数。
-
return f(*args,**kwargs) #根据实际传入参数,在装饰器内部调用被装饰函数。
-
return iner
-
-
@wrap2
-
def func2(a,b,c): #3个参数的
-
pass
-
func2("a",2,4)
-
-
@wrap2
-
def func2(a):#1个参数的
-
pass
-
func2("a")
以上是2个不同函数 func1,func2.
这个wrap2装饰器,返回的是iner函数,不再是原f函数,该iner函数可接受任意参数。接受任意参数后,f函数在装饰器内部进行调用 :f(*args,**kwargs) (根据原函数实际参数进行)
通过这种装换具有很大灵活性。理解重要一点是:该装饰器返回的是什么函数
有时候,希望装饰器本身也要参数 ,增强多样性。如何操作?
很简单
-
def wrap2(arg:str): #第一层传递装饰器参数
-
print(hello)
-
def decordator(f): #第二层 定义:传递被装饰函数
-
def iner(*args,**kwargs): #第3层,定义:替换原先被装饰函数,改变参数约定
-
return f(*args,**kwargs) #最终在装饰内调用被装饰函数
-
return iner # 返回第三层(最后一层),以备按照iner函数形式(变参形式)进行调用
-
return decordator 对应返回第二层函数,用于下次传入被装饰函数
-
-
@wrap2("hello")
-
def test(a):
-
pass
-
-
-
调用
-
test("aaa")
调用可理解如下
wrap2("hello")(test)("aaa")
阅读(36981) | 评论(0) | 转发(0) |