python装饰器的参数传递
python装饰器的参数传递
被装饰器装饰的函数名即使没有被调用(因为有@xxx,会触发运行装饰器),(装饰器工厂函数)定义装饰器的代码已经运行了(最内部的那个函数并没有运行)(把被装饰的原函数引用赋值给了装饰器内部的那个函数名),当下边通过该函数名调用时,会调用到装饰器内部的那个函数()
装饰器:在不修改函数源代码的基础上,添加函数功能
一个简单的装饰器
|
1
2
3
4
5
6
7
8
9
10
11
|
def log_time(func): # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用 def make_decorater(): print('现在开始装饰') func() print('现在结束装饰') return make_decorater # log_time()被调用后,运行此函数返回make_decorater()函数的引用make_decorater@log_time # 此行代码等同于,test=log_time(test)=make_decoraterdef test(): print('我是被装饰的函数')test() # test()=make_decorater() |
|
1
2
3
4
5
6
|
D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py现在开始装饰我是被装饰的函数现在结束装饰Process finished with exit code 0 |
当被装饰的函数有形参时
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def log_time(func): def make_decorater(*args,**kwargs): # 接受调用语句的实参,在下面传递给被装饰函数(原函数) print('现在开始装饰') test_func = func(*args,**kwargs) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回 print('现在结束装饰') return test_func # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。 return make_decorater@log_timedef test(num): print('我是被装饰的函数') return num+1a = test(2) # test(2)=make_decorater(2)print(a) |
|
1
2
3
4
5
6
7
|
D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py现在开始装饰我是被装饰的函数现在结束装饰3Process finished with exit code 0 |
当@装饰器后有参数时
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def get_parameter(*args,**kwargs): # 工厂函数,用来接受@get_parameter('index.html/')的'index.html/' def log_time(func): def make_decorater(): print(args,kwargs) print('现在开始装饰') func() print('现在结束装饰') return make_decorater return log_time@get_parameter('index.html/')def test(): print('我是被装饰的函数') # return num+1test() # test()=make_decorater() |
|
1
2
3
4
5
6
7
|
D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py('index.html/',) {}现在开始装饰我是被装饰的函数现在结束装饰Process finished with exit code 0 |
两个装饰器同时修饰一个函数(重点看执行顺序)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
def log_time1(func): def make_decorater(*args,**kwargs): print('1现在开始装饰') test_func = func(*args,**kwargs) print('1现在结束装饰') return test_func return make_decoraterdef log_time2(func): def make_decorater(*args,**kwargs): # 接受调用语句的实参,在下面传递给被装饰函数(原函数) print('2现在开始装饰') test_func = func(*args,**kwargs) # 如果在这里return,则下面的代码无法执行,所以引用并在下面返回 print('2现在结束装饰') return test_func # 因为被装饰函数里有return,所以需要给调用语句(test(2))一个返回,又因为test_func = func(*args,**kwargs)已经调用了被装饰函数,这里就不用带()调用了,区别在于运行顺序的不同。 return make_decorater@log_time1@log_time2def test(num): print('我是被装饰的函数') return num+1a = test(2) # test(2)=make_decorater(2)print(a) |
|
1
2
3
4
5
6
7
8
9
|
D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/装饰器.py1现在开始装饰2现在开始装饰我是被装饰的函数2现在结束装饰1现在结束装饰3Process finished with exit code 0 |
注意看执行结果(print,只有执行就会输出到屏幕)(return将数据返回给接受的变量或引用)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def makeBold(fn): def wrapped1(): print('1') b = "<b>" + fn() + "</b>" # 此行fn()调用了wrapped(),所以wrapped()执行了print输出到屏幕,然后fn()接受到了wrapped() return返回的结果"<i>" + fn() + "</i>",所以需要等待wrapped()<br> print('1end') # 只有b = "<b>" + fn() + "</b>"执行完毕才会执行这一行,只有wrapped()函数 return返回后,上一行代码才执行<br> return b return wrapped1def makeItalic(fn): def wrapped(): print('2') a = return "<i>" + fn() + "</i>" # 此行fn()调用了test3(),所以test3()执行了,然后fn()接受到了test3()中returnd返回的结果"hello world-3",所以需要等待test3<br> print('2end') # 当test3()返回后,上一行代码执行完毕,在屏幕上输出此行<br> return a return wrapped@makeBold@makeItalicdef test3(): return "hello world-3" # return 给了wrapped,wrapped又return给了wrapped;a = test3() # 此行test3() = wrapped1(),test3()调用了函数所以装饰器才执行。a接受了装饰器return的结果print(a) |
|
1
2
3
4
5
6
|
D:\pycharm_project\装饰器\venv\Scripts\python.exe D:/pycharm_project/装饰器/venv/text.py12<br>2end<br>1end<b><i>hello world-3</i></b>Process finished with exit code 0 |
浙公网安备 33010602011771号