④ 一些实用的代码片段
下面提供一些很实用的代码片段,用到的时候复制粘贴即可:
import datetime import time now = datetime.datetime.now() # 获得当前时间的前/后几天,几小时,几秒,毫秒 # 如果是想获得时间戳可以直接调用int(time.mktime(求出来的时间.timetuple())) def fetch_before_time(time_type, value, strf="%Y-%m-%d %H:%M:%S"): if time_type == 'days': if value > 0: return (datetime.datetime.now() + datetime.timedelta(days=value)).strftime(strf) else: return (datetime.datetime.now() - datetime.timedelta(days=value)).strftime(strf) elif time_type == 'hours': if value > 0: return (datetime.datetime.now() + datetime.timedelta(hours=value)).strftime(strf) else: return (datetime.datetime.now() - datetime.timedelta(hours=value)).strftime(strf) elif time_type == 'seconds': if value > 0: return (datetime.datetime.now() + datetime.timedelta(seconds=value)).strftime(strf) else: return (datetime.datetime.now() - datetime.timedelta(seconds=value)).strftime(strf) elif time_type == 'microseconds': if value > 0: return (datetime.datetime.now() + datetime.timedelta(microseconds=value)).strftime(strf) else: return (datetime.datetime.now() - datetime.timedelta(microseconds=value)).strftime(strf) # 获得第二天凌晨的时间戳 def fetch_morning_timestamp(): return int(time.time()) + (144000 - (int(time.time())) % 86400) # 构造一个由起始事件到结束时间间所有的日期列表 def init_date_list(begin_date, end_date): date_list = [] begin_date = datetime.datetime.strptime(str(begin_date), "%Y%m%d") end_date = datetime.datetime.strptime(str(end_date), "%Y%m%d") while begin_date <= end_date: date_str = begin_date.strftime("%Y%m%d") date_list.append(date_str) begin_date += datetime.timedelta(days=1) return date_list if __name__ == '__main__': print("当前时间:", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) print(fetch_before_time('days', 3)) print(fetch_before_time('hours', -3)) print(fetch_before_time('seconds', 3)) print("第二天早上的时间戳:", fetch_morning_timestamp()) print("从20190101到20190301的日期列表:%s" % init_date_list(20190101, 20190301))
运行结果如下:
当前时间: 2019-03-14 15:44:58 2019-03-17 15:44:58 2019-03-14 18:44:58 2019-03-14 15:45:01 第二天早上的时间戳: 1552665600 从20190101到20190301的日期列表:['20190101', '20190102',...过长省略... '20190226', '20190227', '20190228', '20190301']
2、logging日志模块
大部分的程序都会有「记录运行日志的需求」,而日志信息一般有这样几类:正常的程序运行日志,调试,错误或警告信息的输出等。而日常开发中我们需要把日志持久化到本地,进行一些观察和统计,错误排查等,如果只用print函数输出的话,显然有点捉襟见寸。在Python内置了一个日志模块:logging,它提供了标准的日志接口,支持日志分级和存储。
① 日志分级
在开始正式学习logging前,我们先了解下「日志分级」,即:什么时候用什么等级的日志。如下表所示:
级别 | 建议什么时候使用 |
DEBUG | 详细的信息,常用于问题诊断 |
INFO | 记录关键节点信息,用于确认程序是否按照预期运行 |
WARNING | 程序还是正常运行,但某些不期望的事情发生时记录的信息(如磁盘可用空间较低) |
ERROR | 由于更严重的问题导致某些功能不能正常运行时记录的信息 |
CRITICAL | 发生严重错误,导致程序不能继续运行时记录的信息 |
打印各种级别的代码示例如下:
import logging if __name__ == '__main__': # 获得一个Logger logger = logging.getLogger("Test") # logging提供的简单的配置方法,自行配置的话需要手动添加handler logging.basicConfig() # 设置输出的log级别(大于或等于此级别的才会输出),默认级别Warning logger.setLevel(logging.INFO) logger.debug("=== Debug 级别的信息 ===") # 不会输出 logger.info("=== Info 级别的信息 ===") logger.warning("=== Warning 级别的信息 ===") logger.error("=== Error 级别的信息 ===") logger.critical("=== Critical 级别的信息 ===")
运行结果如下:
INFO:Test:=== Info 级别的信息 === WARNING:Test:=== Warning 级别的信息 === ERROR:Test:=== Error 级别的信息 === CRITICAL:Test:=== Critical 级别的信息 ===
② 将日志写入到文件
日志默认是输出到Console(屏幕)上,如果我们想把详细的日志输出到log文件里,则需要用到handler
了,理论上可以把日志输出到各种流中,stderr、文件、socket等都可以,在logging中已经将各种流handler封装好了,你也可以继承StreamHandler类自己做一些定制,简单的把日志写入到文件中的代码示例如下:
import logging if __name__ == '__main__': logger = logging.getLogger("Test") logger.setLevel(logging.INFO) # 输出到控制台 logger.addHandler(logging.StreamHandler()) # 输出到文件 logger.addHandler(logging.FileHandler('test.log', encoding='UTF-8')) logger.debug("=== Debug 级别的信息 ===") logger.info("=== Info 级别的信息 ===") logger.warning("=== Warning 级别的信息 ===") logger.error("=== Error 级别的信息 ===") logger.critical("=== Critical 级别的信息 ===")
运行结果如下(同时在目录下生成了一个test.log的文件):
=== Info 级别的信息 === === Warning 级别的信息 === === Error 级别的信息 === === Critical 级别的信息 ===
嗯,你可能有这样的需求,Console打印Warning以上的日志,而log文件保存Debug级别以上的日志,那么可以修改下上面的代码,修改后的代码如下:
if __name__ == '__main__': logger = logging.getLogger("Test") logger.setLevel(logging.INFO) # 输出到控制台 s_handler = logging.StreamHandler() s_handler.setLevel(logging.WARNING) logger.addHandler(s_handler) # 输出到文件 f_handler = logging.FileHandler('test.log', encoding='UTF-8') f_handler.setLevel(logging.DEBUG) logger.addHandler(f_handler) logger.debug("=== Debug 级别的信息 ===") logger.info("=== Info 级别的信息 ===") logger.warning("=== Warning 级别的信息 ===") logger.error("=== Error 级别的信息 ===") logger.critical("=== Critical 级别的信息 ===")