2021年7月3日 星期六

[ Python 常見問題 ] Python dynamically add decorator to class' methods by decorating class

 Source From Here

Question
Let's say I have a decorator which will be used to count the times of a function is executed:
  1. def counted(f):    
  2.     def wrapped(*args, **kwargs):    
  3.         wrapped.calls += 1    
  4.         return f(*args, **kwargs)    
  5.     wrapped.calls = 0    
  6.     return wrapped  
  7.   
  8.   
  9. @counted    
  10. def say_hi(name):  
  11.     print(f"Hi, {name}")  
For example:
>>> from test import *
>>> say_hi('John')
Hi, John
>>> say_hi('Ken')
Hi, Ken
>>> say_hi.calls
2
>>> say_hi.__name__
'wrapped'

Then I have new function say_hello
  1. def say_hello(name):  
  2.   print(f"Hello, {name}")  
How can I dynamically add decorator on it so to count the times of execution of it?

HowTo
It is a bit complicated. Let's say your module is test.py. Then you can do it this way:
>>> import test
>>> import inspect
>>> test_func_list = [a for a in dir(test) if inspect.isfunction(getattr(test, a))]
>>> test_func_list # All the functions in module test
['counted', 'say_hello', 'say_hi']

>>> setattr(test, 'say_hello', test.counted(test.say_hello)) # Add decorator @counted in test.say_hello
>>> test.say_hello('Ken')
Hello, Ken
>>> test.say_hello('Jane')
Hello, Jane
>>> test.say_hello.calls # How many times that test.say_hello being called
2
>>> test.say_hello.__name__
'wrapped'


沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...