Replace print? What's wrong with print?
Print is probably the first thing that anyone who learns the Python language touches. Its main function is to print a piece of information to the console, like this:
Copy Code code as follows:
print ' Hello, logging! '
Print is also the most people used to debug their own program with the most things, like writing JS using Console.log as natural. Many beginners who are just starting to learn python and even experienced veterans are using print to debug their code.
For example, this is a small program I wrote to output Fibonacci numbers, so let's take a look at its code:
Copy Code code as follows:
#-*-Coding:utf-8-*-
"""
A Simple Fibonacci Program
"""
Import Argparse
Parser = Argparse. Argumentparser (description= ' I print Fibonacci sequence ')
Parser.add_argument (' s ', '--start ', Type=int, dest= ') Start ',
help= ' Start of the sequence ', required=true)
Parser.add_argument (' e ', '--end ', Type=int, dest= ') End ',
help= ' end of the sequence ', required=true)
Def infinite_fib ():
A, b = 0, 1
yield a
yield b
while True:
#print ' before caculation:a, B =%s,%s ' % (A, b)
A, B = B, a + b
#pr int ' after caculation:a, B =%s,%s '% (A, b)
yield b
def fib (Start, end):
For cur in infinite_fib ():
#print ' cur:%s, start:%s, end:%s '% (cur, start, end)
If cur > End:
Return
If cur >= start:
#print ' Returning result%s '% cur
Yield cur
def main ():
args = Parser.parse_args ()
For N in Fib (Args.start, args.end):
Print N,
if __name__ = = ' __main__ ':
Main ()
Let's take a look at how it works:
Copy Code code as follows:
$ python fib.py-s 1-e 100
1 1 2 3 5 8 13 21 34 55 89
$ python fib.py-s 100-e 1000
144 233 377 610 987
Without any problems, the program completes its function correctly. But wait, what happened to the stack of commented print statements inside the program?
Originally, this is the process of writing this applet, the output information used to debug (debug), after I finished this program, I naturally put these print to comment out. Let's see what happens if we open this print statement.
Copy Code code as follows:
$ python fib.py-s 1-e 100
cur:0, Start:1, end:100
Cur:1, Start:1, end:100
Returning result 1
1 before caculation:a, b = 0, 1
After caculation:a, B = 1, 1
Cur:1, Start:1, end:100
... ...
... ...
(Countless output information)
As you can see, all the calculations are printed out.
When you write with print, you have to remember to delete the print statement when you submit the code, why do we have to endure such a nuisance? Let's introduce our protagonist logging, which is almost always born for this kind of use scenario.
Better practice, using the logging module
The logging module is a python-built log module that makes it easy to process and manage log output. The simplest use of the logging module is to configure the logging directly using the Basicconfig method:
Copy Code code as follows:
Import logging
# Set the default level to debug
# Set the log format
Logging.basicconfig (
Level=logging. DEBUG,
format= "[% (asctime) s]% (name) s:% (levelname) s:% (message) S"
)
# log Log
Logging.debug (...)
Logging.info (...)
Logging.warn (...)
Logging.error (...)
Logging.critical (...)
After you configure logging, then use ' logging.debug ' to replace all print statements. We'll see the output like this:
Copy Code code as follows:
[2014-03-18 15:17:45,216] root:cur:0, Start:1, end:100
[2014-03-18 15:17:45,216] root:debug:cur:1, Start:1, end:100
[2014-03-18 15:17:45,216] root:DEBUG:Returning result 1
[2014-03-18 15:17:45,216] Root:DEBUG:Before caculation:a, b = 0, 1
... ...
Using the real Logger
The Basicconfig method described above can satisfy your use requirements in most scenarios, but Basicconfig has a big drawback.
Calling Basicconfig is actually adding a handler to root logger so that when your program works with other third-party modules that use logging, it can affect the logger behavior of third-party modules. This is determined by the inheritance characteristics of the logger.
So we need to use the real logger:
Copy Code code as follows:
Import logging
# using a logger named fib
Logger = Logging.getlogger (' fib ')
# Set the level of logger to debug
Logger.setlevel (logging. DEBUG)
# Create an output log to the console Streamhandler
HDR = logging. Streamhandler ()
Formatter = logging. Formatter (' [% (asctime) s]% (name) s:% (levelname) s:% (message) s ')
Hdr.setformatter (Formatter)
# Add Handler to Logger
Logger.addhandler (HDR)
This allows you to use logger for log output. But the downside is that the code is a lot bigger than basicconfig. So I suggest if it is very simple small script, directly use basicconfig can, if it is slightly larger some items, the proposal carefully configure good logger.
All output of dynamic control scripts
After using the logging module, by modifying the log level of logger, we can easily control the output of the program. For example, we can add a-v parameter to our Fibonacci sequence to control the printing of all debugging information.
Copy Code code as follows:
# Add receive a verbose parameter
Parser.add_argument ('-V ', '--verbose ', action= ' store_true ', dest= ' verbose ',
help= ' Enable Debug Info ')
# Judge Verbose
If Args.verbose:
Logger.setlevel (logging. DEBUG)
Else
Logger.setlevel (logging. ERROR)
This way, by default, our applet does not print debug information, and only when we pass in '-v/--verbose ' will we print out additional debug information, like this:
Copy Code code as follows:
$ python fib.py-s 1-e 100
1 1 2 3 5 8 13 21 34 55 89
$ python fib.py-s 1-e 100-v
[2014-03-18 15:17:45,216] fib:debug:cur:0, Start:1, end:100
[2014-03-18 15:17:45,216] fib:debug:cur:1, Start:1, end:100
[2014-03-18 15:17:45,216] fib:DEBUG:Returning result 1
[2014-03-18 15:17:45,216] Fib:DEBUG:Before caculation:a, b = 0, 1
... ...
As you can see, when you use the logging, when you need to print debug information, when you need to shut down, everything becomes extremely simple.
So, quickly replace the print in your script with logging!
Extended Reading
These are just some of the simplest features of the logging module, used as a substitute for print, and the logging module has many very powerful features, such as reading configuration from files, various handlers, and so on. Suggest reading the official documents of logging:
1.logging Logging Facility for Python
2.Logging HOWTO
Finally, the complete code for the Fibonacci sequence with the logging module is attached:
Copy Code code as follows:
#-*-Coding:utf-8-*-
"""
A Simple Fibonacci Program
"""
Import Argparse
Parser = Argparse. Argumentparser (description= ' I print Fibonacci sequence ')
Parser.add_argument (' s ', '--start ', Type=int, dest= ' start ',
Help= ' Start of the sequence ', required=true)
Parser.add_argument (' e ', '--end ', type=int, dest= ' End ',
Help= ' end of the sequence ', required=true)
Parser.add_argument ('-V ', '--verbose ', action= ' store_true ', dest= ' verbose ',
help= ' Enable Debug Info ')
Import logging
Logger = Logging.getlogger (' fib ')
Logger.setlevel (logging. DEBUG)
HDR = logging. Streamhandler ()
Formatter = logging. Formatter (' [% (asctime) s]% (name) s:% (levelname) s:% (message) s ')
Hdr.setformatter (Formatter)
Logger.addhandler (HDR)
Def INFINITE_FIB ():
A, b = 0, 1
Yield a
Yield b
While True:
Logger.debug (' before caculation:a, B =%s,%s '% (A, b))
A, B = B, A + b
Logger.debug (' after caculation:a, B =%s,%s '% (A, b))
Yield b
def fib (Start, end):
For cur in infinite_fib ():
Logger.debug (' cur:%s, start:%s, end:%s '% (cur, start, end))
If cur > End:
Return
If cur >= start:
Logger.debug (' Returning result%s '% cur)
Yield cur
def main ():
args = Parser.parse_args ()
If Args.verbose:
Logger.setlevel (logging. DEBUG)
Else
Logger.setlevel (logging. ERROR)
For N in Fib (Args.start, args.end):
Print N,
if __name__ = = ' __main__ ':
Main ()