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_decorater def 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_time def test(num):     print('我是被装饰的函数')     return num+1   a = 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 现在开始装饰 我是被装饰的函数 现在结束装饰 3   Process 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+1   test()  # 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_decorater   def 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_time2 def test(num):     print('我是被装饰的函数')     return num+1   a = 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/装饰器.py 1现在开始装饰 2现在开始装饰 我是被装饰的函数 2现在结束装饰 1现在结束装饰 3   Process 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 wrapped1   def 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 @makeItalic def 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.py 1 2<br>2end<br>1end <b><i>hello world-3</i></b>   Process finished with exit code 0

 

上一篇:VSCode 运行go test显示打印日志


下一篇:nacos远程服务器部署,总是显示localhost:8848而不是远程ip