当被装饰的函数有参数怎么处理,先看一下下面例子:
def test(fun):
print('---test----')
def test_in():
print('----test_in---')
return 'test_in'+fun+'test_in'
return test_in
@test
def fun(a,b): #传形参
print('----fun----')
return "hello"
print(fun(2,3))
运行结果:
Traceback (most recent call last):
File "C:/workspace/pythonTest/pythonDemo/propara.py", line 14, in <module>
print(fun(2,3))
---test----
TypeError: test_in() takes 0 positional arguments but 2 were given
为什么会报错:
- @ test 意思就是 fun=test(fun) , fun 指向是 test_in 函数体
- 在执行 fun(2,3) 的时候 要执行 test_in 函数体, 但是test_in 没有地方接受参数, 所以要报错
下边我们添加上 继续执行看看结果如何:
def test(fun):
print('---test----')
def test_in(a,b): #传形参
print('----test_in---')
return 'test_in'+fun()+'test_in'
return test_in
@test
def fun(a,b): #传形参
print('----fun----')
return "hello"
print(fun(2,3))
再来看一下执行结果:
---test----
----test_in---
Traceback (most recent call last):
File "C:/workspace/pythonTest/pythonDemo/propara.py", line 14, in <module>
print(fun(2,3))
File "C:/workspace/pythonTest/pythonDemo/propara.py", line 5, in test_in
return 'test_in'+fun()+'test_in'
TypeError: fun() missing 2 required positional arguments: 'a' and 'b'
解释如下:
在执行test_in 函数体的时候, 发现有个 func(), 它的指向 就是 f1(a,b) , 它是需要两个参数的, 但是找不到,就会报错
改下 再执行就不会报错了
def test(fun):
print('---test----')
def test_in(a,b): #传形参
print('----test_in---')
return 'test_in'+fun(a,b)+'test_in' #传形参
return test_in
@test
def fun(a,b): #传形参
print('----fun----')
return "hello"
print(fun(2,3))
运行结果:
---test----
----test_in---
----fun----
test_inhellotest_in
此时我们已经知道哪些地方需要加形参了,再想一下如果每次参数个数不定,是不是每次都需要在三个地方修改参数,很不方便,因此我们使用不定长参数进行修改;
def test(fun):
print('---test----')
def test_in(*args): #传不定长形参
print('----test_in---')
return 'test_in '+str(fun(*args))+' test_in' #传形参
return test_in
@test
def fun(a,b,c): #根据需要传参数
print('----fun----')
return (a+b+c)
@test
def fun1(a,b,c,d):
print('----fun1----')
return a+b+c+d
print(fun(2,3,4)) #根据需要进行传入参数都可以
print(fun1(2,3,4,5))
运行结果:
---test----
---test----
----test_in---
----fun----
test_in 9 test_in
----test_in---
----fun1----
test_in 14 test_in
但是看下一个情况:
如果传入了关键字形式的键值对:
def test(fun):
print('---test----')
def test_in(*args): #传形参
print('----test_in---')
return 'test_in '+str(fun(*args))+' test_in' #传形参
return test_in
@test
def fun(a,b,c): #传形参
print('----fun----')
return (a+b+c)
@test
def fun1(a,b,c,d):
print('----fun1----')
return (a+b+c+d)
print(fun(2,3,4))
print(fun1(a=1,b=3,c=4,d=5))
运行会报错:
发现当传入字典形式的不定长参数时需要使用**kwargs注意两个地方都需要修改:
完整的修饰不定长参数的装饰器写法如下:
def test(fun):
print('---test----')
def test_in(*args,**kwargs): #传形参
print('----test_in---')
return 'test_in '+str(fun(*args,**kwargs))+' test_in' #传形参
return test_in
@test
def fun(a,b,c): #传形参
print('----fun----')
return (a+b+c)
@test
def fun1(a,b,c,d):
print('----fun1----')
return (a+b+c+d)
print(fun(2,3,4))
print(fun1(a=1,b=3,c=4,d=5))
运行结果如下:
---test----
---test----
----test_in---
----fun----
test_in 9 test_in
----test_in---
----fun1----
test_in 13 test_in