来调解他们的代码

替换print?print怎么了?

print
或者是负有学习Python语言的人第3个接触的事物。它最关键的功力正是往调节台
打字与印刷一段音讯,像这么:

复制代码 代码如下:

print ‘Hello, logging!’

print也是绝大诸多人用来调治自身的次第用的最多的事物,就好像写js使用
console.log
一样那么自然。许多刚刚起始学习Python的菜鸟乃至有必然经验的老资格,都在选用print
来调治他们的代码。

诸如那是一个自小编写的输出 斐波那契数列 的小程序,让大家来看望它的代码:

复制代码 代码如下:

# -*- 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
        #print ‘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()

让大家来探视它工作的哪些:

复制代码 代码如下:

$ 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

尚未其他难题,程序正确的成就了它的职能。但等等,
程序里面包车型客车那一批被解说掉的print语句是怎么回事?

原本,那是本人编写那么些小程序的进度中,用来 调节和测试(DEBUG)
的输出消息,在自家成功了那些程序之后,小编本来就把那一个print给注释掉了。让大家来看看假使把这些print语句展开后结果会怎么着?

复制代码 代码如下:

$ 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
… …
… …
(不计其数的出口消息)

如您所见,全部的计算进程都被打字与印刷出来了。

写的时候增加print,提交代码的时候还得记得把print语句删掉/注释掉,为啥大家要忍受那样的闲事呢?
让大家来介绍大家的栋梁 logging ,它大约正是为这种利用情形而生的。

越来越好的做法,使用logging模块

logging模块是Python内置的日记模块,使用它能够非常轻易的拍卖和保管日志输出。
logging模块最简便的用法,是一向动用basicConfig方法来对logging实行安排:

复制代码 代码如下:

import logging

# 设置暗许的level为DEBUG
# 设置log的格式
logging.basicConfig(
    level=logging.DEBUG,
    format=”[%(asctime)s] %(name)s:%(levelname)s: %(message)s”
)

# 记录log
logging.debug(…)
logging.info(…)
logging.warn(…)
logging.error(…)
logging.critical(…)

那样布署完logging今后,然后利用“logging.debug“来替换全体的print语句就足以了。
大家会看出那样的输出:

复制代码 代码如下:

[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
… …

使用真正的logger

地点说的basicConfig方法能够满意你在多数风貌下的施用要求,可是basicConfig有3个十分的大的重疾。

调用basicConfig其实是给root
logger增添了3个handler,那样当你的次第和别的使用了
logging的第一方模块一同坐班时,会影响第二方模块的logger行为。那是由logger的后续性格决定的。

为此大家必要使用真正的logger:

复制代码 代码如下:

import logging

# 使用2个名为fib的logger
logger = logging.getLogger(‘fib’)

# 设置logger的level为DEBUG
logger.setLevel(logging.DEBUG)

# 创制贰个出口日志到调节台的StreamHandler
hdr = logging.StreamHandler()
formatter = logging.Formatter(‘[%(asctime)s] %(name)s:%(levelname)s:
%(message)s’)
hdr.setFormatter(formatter)

# 给logger添加上handler
logger.addHandler(hdr)

那般再采纳logger来展开日志输出就行了。不过如此的弊病正是代码量比basicConfig要大不少。
所以小编提出壹旦是特别轻易的小本子的话,直接接纳basicConfig就足以,假若是有些大片段
项目,建议认真布置好logger。

动态调控脚本的持有出口

选用了logging模块然后,通过退换logger的log
level,我们就可以方便的支配程序的出口了。
比方我们得感到大家的斐波那契数列增多三个 -v
参数,来调控打字与印刷全部的调节和测试音信。

复制代码 代码如下:

# 增添接收一个verbose参数
parser.add_argument(‘-v’, ‘–verbose’, action=’store_true’,
dest=’verbose’,
                    help=’Enable debug info’)

# 判断verbose
if args.verbose:
    logger.setLevel(logging.DEBUG)
else:
    logger.setLevel(logging.ERROR)

诸如此类,暗中认可情形下,我们的小程序是不会打字与印刷调节和测试消息的,唯有当传入`-v/–verbose`的时候,
大家才会打字与印刷出额外的debug消息,就好像这么:

复制代码 代码如下:

$ 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
… …

如你所见,使用了logging以往,什么日期需求打字与印刷DEBUG信息,曾几何时须求关闭,
一切变的特别轻松。

故此,赶紧用logging替换掉你的台本里的print吧!

延长阅读

如上这么些只是介绍了logging模块最简易的部分意义,作为print的代表品来使用,logging
模块还有繁多相当强大好用的功用,比方从文件读取配置、美妙绝伦的Handlers等等。
提出阅读一下logging的官方文书档案:

1.logging Logging facility for
Python
2.Logging HOWTO

末段附上使用logging模块的斐波那契数列程序完整代码:

复制代码 代码如下:

# -*- 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()

您也许感兴趣的稿子:

  • Python中动用logging模块打印log日志详解
  • python中使用sys模板和logging模块获取行号和函数名的秘技
  • 缓慢解决Python中出于logging模块误用导致的内部存款和储蓄器走漏
  • python中国和东瀛志logging模块的性质及多进程详解
  • 详解使用python的logging模块在stdout输出的二种艺术
  • 详解Python自建logging模块
  • Python三.七日志Logging模块轻松用法示例
  • python使用logging模块发送邮件代码示例
  • Python
    logging模块用法示例
  • Python使用logging模块达成打字与印刷log到钦定文件的法子

相关文章