Python: the correct way to enter a single file from different modules

Over time, I wrote a bunch of scripts, and I save DRY code in the process of refactoring scripts. I am currently using something in these lines in various scenarios:

if __name__ == '__main__': logger = logging.getLogger('dbinit') hdlr = logging.FileHandler('/var/logs/tmp/foo.log') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') hdlr.setFormatter(formatter) logger.addHandler(hdlr) logger.setLevel(logging.WARNING) 

Instead of repeating this in every script (ie, “module”), I would like this initialization of the login to be done somewhere and available for different scripts (Hmm, perhaps wrapping in a singleton class?).

If I cannot do this (i.e. put the log initialization code in one main module), I assume that using the same log file name in the logging.FileHandler () call, different scripts will be written to the same file .

Is this assumption correct?

Last but not least, what is the best practice (i.e. Pythonic) to solve this problem?

+6
source share
3 answers

Given that you are using if __name__ == __main__ , I assume that these scripts will work as different processes. In this case, you should use a separate configuration file.

This configuration can be stored in a file in the format specified in the documents. Then you can use logging.config.fileConfig to download the file. You can also save the configuration in JSON / YAML formats, convert it to a dictionary, and load using logging.config.dictConfig . The latter is the current recommended approach, although I find it more direct. Read this one for more information.

The advantages of using the configuration file approach multiple times:

  • It saves configuration settings separately from your code.
  • This allows non-programmers to make configuration changes, as they are stored in easily readable formats.
  • It also forces you not to repeat, as you already mentioned.
+1
source

create a function in your python module as below:

 def createLogHandler(job_name,log_file): logger = logging.getLogger(job_name) ## create a file handler ## handler = logging.FileHandler(log_file) ## create a logging format ## formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) return logger 

Now call the function in your program as follows:

 job_name = 'dbinit' log_file = '/var/logs/tmp/foo.log' logger = createLogHandler(job_name ,log_file ) logger.info('Logger has been created') 
0
source

(...) addHandler () will not add a handler if the handler already exists , so the presence of such an initialization code in many places will not hurt.

If I cannot do this (for example, put the registrar initialization code in one main module)

You can do this, and you must do this if you want the initialization code to run once.

-1
source

Source: https://habr.com/ru/post/911804/


All Articles