How to solve the problem of using Python decorator
This article mainly explains "how to solve the problems in the use of Python decorator", the content of the explanation is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "how to solve the problems in the use of Python decorator" bar!
Doubt
First of all, I have a decorator file path like helper/log_helper.py
Import traceback from functools import wraps from loguru import logger def my_logger (count): def step1 (foo): @ wraps (foo) def step2 (* args, * * kwargs): try: result= foo (* args, * * kwargs) logger.info (f "{result=}) {count=} ") except Exception: logger.exception (traceback.format_exc ()) return step2 return step1
Then I have a file that needs to refer to the decorator demo.py
From helper.log_helper import my_logger class Demo: @ my_logger (count=2) def main (self): return "in main function" if _ _ name__ ='_ _ main__': d = Demo () d.main ()
The output is as follows
2020-10-16 11 11 result='in main function',count=2 4312. 001 | INFO | helper.log_helper:step2:18-result='in main function',count=2
The purpose of this decorator is very simple, which is to get the return value of the current function and the count value passed in.
Okay, now the problem is?
What if I pass a value to the parameter of the decorator, which means that my count=2 is in the form of passing a value. You thought it might be like this.
From helper.log_helper import my_logger COUNT=2 class Demo: @ my_logger (count=COUNT) def main (self): return "in main function" if _ _ name__ ='_ _ main__': d = Demo () d.main ()
Ok, this does work, and we can use it to simplify it a little bit.
From functools import partial from helper.log_helper import my_logger COUNT=2 my_logger = partial (my_logger,count=2) class Demo: @ my_logger () def main (self): return "in main function" if _ _ name__ ='_ _ main__': d = Demo () d.main ()
For the time being, we have solved the problem of passing parameters, and we thought, what if the main method of the Demo class is called and the value of count is specified?
We know that the only way for outsiders to call the Demo class to pass parameters is to pass parameters to _ _ init__. According to this line of thinking, we can only write this.
Class Demo: def _ _ init__ (self): count= 2 @ my_logger (count=self.count) def main (self): return "in main function"
But that doesn't work. We get the wrong message.
NameError: name 'self' is not defined
You cannot use self in the decorator. Formal parameters, can't this problem be solved?
Problem solving
There is really no feasible plan before Python3.7.
We know that dataclasses was introduced in Python3.7, and we can use it to simplify _ _ init__.
Change our code.
From functools import partial from helper.log_helper import my_logger from dataclasses import dataclass @ dataclass () class Demo: count: int = 2 logger: my_logger = partial (my_logger, count) @ logger () def main (self): return "in main function" if _ _ name__ ='_ main__': d = Demo () d.main ()
If you use Python3.8, you can just ignore dataclass.
Class Demo: count: int = 2 logger: my_logger = partial (my_logger, count) @ logger () def main (self): return "in main function" Thank you for reading. The above is the content of "how to solve the problem of using Python decorator". After the study of this article, I believe you have a deeper understanding of how to solve the problem of using Python decorator. The specific use situation still needs to be verified by practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!