B树是一种多路查找树,相关的定义与解释解释如下。
Python_装饰器
W3C文档 , 此文档与文档底下的第一个评论均很好的解释了装饰器的作用这里没有全部列出.
Python_类变量与实例变量
Python_方法的种类
Python_内存管理
Python_值传递与引用传递
Python_OrderDict
reference Adress:official Doc Learning Bolg
Python_new与init
乍看一下上面两个方法功能相似,但其是其存在区别。
Python_metaclasses
元类概念在平时的使用中是很少涉及到的,其核心理解概括为一句话就是类的类。在Python中我们常见的就是构建一个类,并且实例化这个类,并继续相关的操作。而类本身其实也是一个对象,其是元类的示例。 上面给定的博客地址就是讲的很详细,如果需要的化再去做相关的文档好了。
Python_Logging
python 3.7
Logging是什么
Logging包是Python的标准包之一,可用于代码事件追踪.事件也是分等级的,一般而言不同类型的事件所采用的策略是不同的.
Logging提供的常用接口
Logging针对不同等级的事件,提供了以下默认接口:debug() , info() , warning() , error() , critical().以下的表格展示了代码中事件的级别以及相应的追踪方法:
追踪任务 | 推荐使用的工具 |
---|---|
日常使用中展示控制台的输出 | print() |
日程程序操作中报告某事件的发生 | logging.info()/logging.debug() |
程序运行时提出警告信息 | logging.warning()/warning.warn() |
程序运行时出错 | Raise exception |
程序运行时出错但不抛出异常 | logging.error()/logging.exception()/logging.critical() |
我们发现对于不同等级的事件,对应这不同的解决方式,其有不同的名称:比如:DEBUG,INFO等.这些名称的含义如下表展示:
Level | When it’s used |
---|---|
DEBUG | Detailed information, typically of interest only when diagnosing problems. |
INFO | Confirmation that things are working as expected. |
WARNING | An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR | Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL | A serious error, indicating that the program itself may be unable to continue running. |
看到这里应该对事件级别有了大概的认识,logging包中默认的追踪级别时DEBUG;
在日常使用时,我们最常用的事件追踪方式就两种:
- 打印到控制台;
- 写到硬盘文件中;
Logging的基本使用方式
代码示例
简单示例
直接调用logging.debug()等接口即可,在控制台输出对应格式;
1 | import logging |
上面代码只输出了warning()方法的信息,这是由于logging默认只追踪DEBUG(包括)之上的日志信息.
默认输出格式:
1 | LEVEL:INFORMATION |
我们发现相较于默认的输出格式,还有一个root被输出出来,这里的root指的时logger的层次.
输出到文件示例
1 | import logging |
输出文件内容:
1 | DEBUG:root:This message should go to the log file |
通过设置basicConfig()进行相关设置,细节这里不写;
更改文件的输出格式:format关键字
1 | import logging |
输出内容:
1 | DEBUG:This message should appear on the console |
添加时间到输出格式中:%(asctime)s
1 | import logging |
输出内容;
1 | 2010-12-12 11:41:42,612 is when this event was logged. |
定制时间格式:datafmt关键字
1 | import logging |
输出内容:
1 | 12/12/2010 11:46:36 AM is when this event was logged. |
format参数
在logging.basicConfig()方法内,format起着调整输出格式的作用.岂可选参数如下:
1 | `%(asctime)s` 表示当前时间,格式为`2018-07-01 19:08:41,050`,逗号后面是毫秒 |
datefmt
对时间格式进行修改
使用例子如下
1 | import logging |
输出结果如下
1 | Sun, 01 Jul 2018 19:19:00 +0000 this is a info |
datefmt
的格式可以参考官网表格
style
默认为%
,可选{
和$
,他们的使用方法分别如下
1 | # % |
Logging的高级使用方式
高级模块无非是可以定制化log的生成,存储,具体格式等内容.上面的简单示例已经或多或少的有所触及,比如通过format关键字指定输出格式,通过filename关键字指定log存储文件地址,等等.
在logging中,分布有四个模块,每个模块都包含有特定的功能,分别是:logger,handler,filter,formatter;
模块解释
- Loggers expose the interface that application code directly uses.
- Handlers send the log records (created by loggers) to the appropriate destination.
- Filters provide a finer grained facility for determining which log records to output.
- Formatters specify the layout of log records in the final output.
Log事件信息会在上述四个模块间传递,最终得到你想要的log日志信息;
Logger
Logger对象是logging的核心对象,其任务可以简单的分为产生信息并传递给下一模块,具体有三:
- 提供了多种接口,用于运行时记录相关信息.这里说的接口与logging类一致:debug(),info(),warning(),error(),etc;
- Logger对象可以决定处理什么等级的信息,可以通过默认关键字(level)设置或者filter对象;
- Logger对象可以将日志信息**传递给相关对象(handler)**进行接下来的处理.
特点:
Logger对象通过名称标识层次,层次间用英文句号分割.例如有三个logger其名称分别为:foo , foo.bar , foo.bar.baz,其分别扮演祖先,父母,与儿子的角色.类似于继承的概念.
一般情况下以当前的模块名称作为logger名称,这也就对模块的规范进行要求.以下是示例:
1 | logger = logging.getLogger(__name__) |
常见方法:
- Logger.setLevel():指定logger需要处理的最低层次信息;
- Logger.addHandler() and Logger.removeHandler():添加与移除Handler对象
- Logger.addFilter() and Logger.removeFilter():添加与移除Filter对象
上述三个方法均具有继承性;
- Logger.debug(),Logger.info(),Logger.warning(),Logger.error(),Logger.critical():产生log信息的方法.其信息均为format string,可通过替代符号”%s,%d,%d”进行设置.
Logger.exception()
creates a log message similar toLogger.error()
. The difference is thatLogger.exception()
dumps a stack trace along with it. Call this method only from an exception handler.Logger.log()
takes a log level as an explicit argument. This is a little more verbose for logging messages than using the log level convenience methods listed above, but this is how to log at custom log levels.
- getLogger():获得logger对象的方法,默认名称为root,可指定.
Handlers
Handlers用来对log进行特定的分派处理,例如将某类型log发送到邮箱或存储在特定文件内.一般情况一个logger对象可以添加多个Handlers对象.
常见方法:
- setLevel():设定进行dispatch的最底层事件
- setFormatter():为handler对象选定格式对象
- addFilter()/removeFilter():配置过滤对象
Formatters
这里没看懂文档解释
示例
配置它们的流程是
- 配置好的format设置到handler中
- 配置好的handler添加到logger中
1 | import logging |
运行结果
1 | 2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message |
创建log流程的多种方式
这里不一一展示
- Creating loggers, handlers, and formatters explicitly using Python code that calls the configuration methods listed above.
- Creating a logging config file and reading it using the
fileConfig()
function. - Creating a dictionary of configuration information and passing it to the
dictConfig()
function.
样例探究Logging的特点
样例地址 上述地址上讲解了各种情况下Logger的使用方式,不需要意义查看,针对自己的场景常看相关样例即可,这里仅介绍第一个样例.
多模块使用Logging的方式
- 模块名称标识Logger的方式,即使在不同模块我们使用相同的名称,也会获得相同的对象;
- 不同模块间建议使用层次化模块名称,名称层次使用句号分割,主模块采用作为父名称,副模块采用子名称.
- 子模块的调用会自动传给父模块;
module.py模块
1 | import logging |
auxiliary_module.py辅助模块
1 | import logging |
输出结果:
1 | 2020-08-14 16:51:52,747 - spam_application - INFO - creating an instance of auxiliary_module.Auxiliary |