在一个完整的信息系统里面,日志系统是一个非常重要的功能组成部分。它可以记录下系统所产生的所有行为。我们可以使用日志系统所记录的信息为系统进行排错,优化系统的性能,或者根据这些信息调整系统的行为。
python 语言也自带了日志模块 logging, 对于熟悉该模块的人使用起来可能是得心应手, 不过对于新手或者只是想简单使用日志基本用法的人来说, 该模块不是那么的友好.为此, 我查询了 python 相关的日志模块, 其中大家推荐比较多的是 logbook 和 logzero, 我查看了下它们的使用文档, 发现 logbook 类似于 logging 模块, 功能比较健全, 不过我没有去详细了解,我被它的文档吓退了. 由于这和我的需求不同, 我只是想简单使用下, 希望模块简约, 各种信息(debug, info, warn, error)颜色鲜明, 能记录下我的"炼丹"信息就好. 幸好, logzero 就是这样的产品, 详细见 logzero 官方文档.
官方文档: logzero: Python logging made easy
pip install -U logzero
pip 参数说明:
-U, --upgrade Upgrade all specified packages to the newest available version. The handling of dependencies depends on the upgrade-strategy used.
logzero 提供了初始化好的 logger 对象, 使用简单, 简单例子如下
import logging
import logzero
from logzero import logger
import os
logger.debug("hello")
logger.info("info")
logger.warning("warning")
logger.error("error")
# set log level
logzero.loglevel(logging.INFO)
# set log into file
logzero.logfile(os.path.join(os.getcwd(), 'log.txt'), maxBytes=1e6, backupCount=3)
# Log messages
logger.info("This log message goes to the console and the logfile")
# set log formatter
logzero.formatter(logging.Formatter('%(name)s-%(asctime)s-%(levelname)s: %(message)s'))
logger.info("This log message goes to the console and the logfile")
import logging
import logzero
from logzero import logger
import os
logger.debug("hello")
logger.info("info")
logger.warning("warning")
logger.error("error")
# set log level
logzero.loglevel(logging.INFO)
# set log into file
logzero.logfile(os.path.join(os.getcwd(), 'log.txt'), maxBytes=1e6, backupCount=3)
# Log messages
logger.info("This log message goes to the console and the logfile")
# set log formatter
logzero.formatter(logging.Formatter('%(name)s-%(asctime)s-%(levelname)s: %(message)s'))
logger.info("This log message goes to the console and the logfile")
输出如下:

各种信息颜色分明, 看着很舒服是吧, 然而, 这样使用着会比较别扭.
首先, 提供的 logger 对象由于是已经初始化好的, 名称不能改变, 日志默认名称为 logzero_default;
其次, 已经创建了 logger, 然后使用 logzero 不断改变 logger 的属性, 用着别扭.
好消息是, logzero 提供了可以自己建立 logger 对象的方法, 使用起来也是简单明了.
1.3 自己构造logger对象
使用方法如下
import logging
import os
from logzero import setup_logger, LogFormatter
# custom formatter must be inited in setup_logger()
logger = setup_logger(name=__name__,
logfile=os.path.join(os.getcwd(), 'log.txt'),
level=logging.INFO,
formatter=logging.Formatter('[%(name)s-%(asctime)s-%(levelname)s] %(message)s'))
var1 = 'happy'
var2 = 'ending'
# Log some variables
logger.info("var1: %s, var2: %s", var1, var2)
import logging
import os
from logzero import setup_logger, LogFormatter
# custom formatter must be inited in setup_logger()
logger = setup_logger(name=__name__,
logfile=os.path.join(os.getcwd(), 'log.txt'),
level=logging.INFO,
formatter=logging.Formatter('[%(name)s-%(asctime)s-%(levelname)s] %(message)s'))
var1 = 'happy'
var2 = 'ending'
# Log some variables
logger.info("var1: %s, var2: %s", var1, var2)
输出:

其中, formatter 默认使用 logzero 的配置, 你也可能像我一样比较喜欢logzero 默认的 formatter 才会使用它, 所以一般不用设置. 上面为演示效果才设置的.
1.4 设置时间输出格式
logzero 默认的时间输出格式如下

日期 190303 可能总感觉没有19-03-03舒服. 格式修改方法如下,
import logging
import os
from logzero import setup_logger, LogFormatter
formatter = LogFormatter(datefmt=logging.Formatter.default_time_format)
# custom formatter must be inited in setup_logger()
logger = setup_logger(name=__name__,
logfile=os.path.join(os.getcwd(), 'log.txt'),
level=logging.INFO,
formatter=formatter)
var1 = 'happy'
var2 = 'ending'
# Log some variables
logger.info("var1: %s, var2: %s", var1, var2)
import logging
import os
from logzero import setup_logger, LogFormatter
formatter = LogFormatter(datefmt=logging.Formatter.default_time_format)
# custom formatter must be inited in setup_logger()
logger = setup_logger(name=__name__,
logfile=os.path.join(os.getcwd(), 'log.txt'),
level=logging.INFO,
formatter=formatter)
var1 = 'happy'
var2 = 'ending'
# Log some variables
logger.info("var1: %s, var2: %s", var1, var2)
输入如下图

logzero 的基本介绍就到这里了, 详细了解请下载, logzero 模块定义在一个文件中, 小巧易用.
二. argparse
argparse 官方教程写的太棒了, 照着走一遍, argparse 基本用法搞定.进阶请查看 python argparse模块介绍.
argparse基本用法:
- 当调用parse_args()时,可选参数将由 “ - ” 前缀标识,其余参数将被假定为位置参数;
- argparse将我们给它的选项视为字符串,除非我们另有说明, 如指定 type;
- 如果参数两个值实际上只有两个值有意义,真或假, 使用 action ="store_true";
- 如果 datatype 为 int,可以使用 choices = [0,1,2] 来限制有效的取值范围;
- 设置 action ="count",args 参数传递可以使用 -v,-vv,-vvv 表示整数 1, 2, 3;
- 如果选项互斥, 可以通过如下设置实现;
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()