day15-包的使用以及logging日志模块

本文介绍Python中包的管理方法,包括包的概念、使用目的及注意事项,并深入探讨logging模块的日志记录功能,涉及日志级别设定、格式化配置等关键知识点。

一、什么是包?

 1 #官网解释
 2 Packages are a way of structuring Python’s module namespace by using “dotted module names”
 3 包是一种通过使用‘.模块名’来组织python模块名称空间的方式。
 4 
 5 #具体的:包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来
 6 
 7 #需要强调的是:
 8   1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
 9 
10   2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块
包的定义

二、为何要使用包

包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来
随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性

三、关于包使用的注意事项

#1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,
否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
#2、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
#3、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间
 1 ############run文件###############
 2 # import pack
 3 # pack.m1.f1() #pack__init_中from pack import m1\# from pack.m1 import  f1
 4 # pack.m2.f2() #pack__init_中from pack import m2\# from pack.m2 import  f2
 5 #
 6 # pack.f1() # from pack.m1 import  f1
 7 # pack.f2() # from pack.m2 import  f2
 8 
 9 
10 #(2)#直接调用f1\f2
11 # from pack.m1 import f1
12 # f1()
13 #
14 # from pack import m2
15 # m2.f2()
16 #
17 # from pack.m2 import f2
18 # f2()
19 
20 #(3)调用pack1f3
21 import  pack
22 pack.f3()
23 
24 
25 #(4)
26 # import pack
27 # pack.f1()
28 第一级__init__下面的代码
29 '''
30 (1、2)2种方法在run函数中调用顺序先在run中导入pack文件夹---然后(1)是导入到模块名只能用
31 pack.m1.f1()、pack.m2.f2()方法调用函数
32 (2)是导入模块命中的函数 调用方法是pack.f1()、pack.f2()  ----pack.m1.f1()、pack.m2.f2()都可以
33 '''
34 
35 #(1) 第一种写法
36 # from pack import m1
37 # from pack import m2
38 
39 #(2)第二种写法
40 # from pack.m1 import  f1
41 # from pack.m2 import  f2
42 
43 #(3)调用pack1中的m3
44 # from pack import pack1 ##等于from .import pack1
45 
46 #(4)调用pack1中的m3
47 # from pack.pack1.m3 import f3
48 
49 from .m1 import f1
50 from .m2 import f2
View Code
1 包的使用之from ... import ...
2 
3 需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法
4  from glance.db import models
5  models.register_models('mysql')
6 
7  from glance.db.models import register_models
8  register_models('mysql')
from... import导入包的注意事项
 1 我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:
 2 
 3 绝对导入:以glance作为起始
 4 
 5 相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)
 6 
 7 例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py
 8 1 在glance/api/version.py
 9 2 
10 3 #绝对导入
11 4 from glance.cmd import manage
12 5 manage.main()
13 6 
14 7 #相对导入
15 8 from ..cmd import manage
16 9 manage.main()
绝对导入和相对导入

 四、logging日志的使用

  (1)、日志级别

CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置

  (2)、默认级别为warning,默认打印到终端

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''

  (3)为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

 1 可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
 2 filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
 3 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
 4 format:指定handler使用的日志显示格式。 
 5 datefmt:指定日期时间格式。 
 6 level:设置rootlogger(后边会讲解具体概念)的日志级别 
 7 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
 8 
 9 
10 
11 #格式
12 %(name)s:Logger的名字,并非用户名,详细查看
13 
14 %(levelno)s:数字形式的日志级别
15 
16 %(levelname)s:文本形式的日志级别
17 
18 %(pathname)s:调用日志输出函数的模块的完整路径名,可能没有
19 
20 %(filename)s:调用日志输出函数的模块的文件名
21 
22 %(module)s:调用日志输出函数的模块名
23 
24 %(funcName)s:调用日志输出函数的函数名
25 
26 %(lineno)d:调用日志输出函数的语句所在的代码行
27 
28 %(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示
29 
30 %(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数
31 
32 %(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
33 
34 %(thread)d:线程ID。可能没有
35 
36 %(threadName)s:线程名。可能没有
37 
38 %(process)d:进程ID。可能没有
39 
40 %(message)s:用户输出的消息
View Code
 1 可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
 2 filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
 3 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
 4 format:指定handler使用的日志显示格式。 
 5 datefmt:指定日期时间格式。 
 6 level:设置rootlogger(后边会讲解具体概念)的日志级别 
 7 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
 8 
 9 
10 
11 #格式
12 %(name)s:Logger的名字,并非用户名,详细查看
13 
14 %(levelno)s:数字形式的日志级别
15 
16 %(levelname)s:文本形式的日志级别
17 
18 %(pathname)s:调用日志输出函数的模块的完整路径名,可能没有
19 
20 %(filename)s:调用日志输出函数的模块的文件名
21 
22 %(module)s:调用日志输出函数的模块名
23 
24 %(funcName)s:调用日志输出函数的函数名
25 
26 %(lineno)d:调用日志输出函数的语句所在的代码行
27 
28 %(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示
29 
30 %(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数
31 
32 %(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
33 
34 %(thread)d:线程ID。可能没有
35 
36 %(threadName)s:线程名。可能没有
37 
38 %(process)d:进程ID。可能没有
39 
40 %(message)s:用户输出的消息
View Code

  (4)、logging模块的Formatter,Handler,Logger,Filter对象

1 #logger:产生日志的对象
2 
3 #Filter:过滤日志的对象
4 
5 #Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端
6 
7 #Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
View Code
 1 '''
 2 critical=50
 3 error =40
 4 warning =30
 5 info = 20
 6 debug =10
 7 '''
 8 
 9 
10 import logging
11 
12 #1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
13 logger=logging.getLogger(__file__)
14 
15 #2、Filter对象:不常用,略
16 
17 #3、Handler对象:接收logger传来的日志,然后控制输出
18 h1=logging.FileHandler('t1.log') #打印到文件
19 h2=logging.FileHandler('t2.log') #打印到文件
20 h3=logging.StreamHandler() #打印到终端
21 
22 #4、Formatter对象:日志格式
23 formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
24                     datefmt='%Y-%m-%d %H:%M:%S %p',)
25 
26 formmater2=logging.Formatter('%(asctime)s :  %(message)s',
27                     datefmt='%Y-%m-%d %H:%M:%S %p',)
28 
29 formmater3=logging.Formatter('%(name)s %(message)s',)
30 
31 
32 #5、为Handler对象绑定格式
33 h1.setFormatter(formmater1)
34 h2.setFormatter(formmater2)
35 h3.setFormatter(formmater3)
36 
37 #6、将Handler添加给logger并设置日志级别
38 logger.addHandler(h1)
39 logger.addHandler(h2)
40 logger.addHandler(h3)
41 logger.setLevel(10)
42 
43 #7、测试
44 logger.debug('debug')
45 logger.info('info')
46 logger.warning('warning')
47 logger.error('error')
48 logger.critical('critical')
详细解说

 

   (5) 、Logger与Handler的级别 

    logger是第一级过滤,然后才能到handler,我们可以给logger和handler同时设置level,但是需要注意的是

重要的点
 1 Logger is also the first to filter the message based on a level — if you set the logger to INFO, and all handlers to DEBUG, you still won't receive DEBUG messages on handlers — they'll be rejected by the logger itself. If you set logger to DEBUG, but all handlers to INFO, you won't receive any DEBUG messages either — because while the logger says "ok, process this", the handlers reject it (DEBUG < INFO).
 2 
 3 
 4 
 5 #验证
 6 import logging
 7 
 8 
 9 form=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
10                     datefmt='%Y-%m-%d %H:%M:%S %p',)
11 
12 ch=logging.StreamHandler()
13 
14 ch.setFormatter(form)
15 # ch.setLevel(10)
16 ch.setLevel(20)
17 
18 l1=logging.getLogger('root')
19 # l1.setLevel(20)
20 l1.setLevel(10)
21 l1.addHandler(ch)
22 
23 l1.debug('l1 debug')
24 
25 重要,重要,重要!!!

  (6)logger的继承

了解知识

  (7)应用

 1 import logging
 2 
 3 formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
 4                     datefmt='%Y-%m-%d %H:%M:%S %p',)
 5 
 6 ch=logging.StreamHandler()
 7 ch.setFormatter(formatter)
 8 
 9 
10 logger1=logging.getLogger('root')
11 logger2=logging.getLogger('root.child1')
12 logger3=logging.getLogger('root.child1.child2')
13 
14 
15 logger1.addHandler(ch)
16 logger2.addHandler(ch)
17 logger3.addHandler(ch)
18 logger1.setLevel(10)
19 logger2.setLevel(10)
20 logger3.setLevel(10)
21 
22 logger1.debug('log1 debug')
23 logger2.debug('log2 debug')
24 logger3.debug('log3 debug')
25 '''
26 2017-07-28 22:22:05 PM - root - DEBUG -test:  log1 debug
27 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
28 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
29 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
30 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
31 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
32 '''
常用字典,格式如下在其中修改需要改的格式即可
 1 import logging
 2 
 3 formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
 4                     datefmt='%Y-%m-%d %H:%M:%S %p',)
 5 
 6 ch=logging.StreamHandler()
 7 ch.setFormatter(formatter)
 8 
 9 
10 logger1=logging.getLogger('root')
11 logger2=logging.getLogger('root.child1')
12 logger3=logging.getLogger('root.child1.child2')
13 
14 
15 logger1.addHandler(ch)
16 logger2.addHandler(ch)
17 logger3.addHandler(ch)
18 logger1.setLevel(10)
19 logger2.setLevel(10)
20 logger3.setLevel(10)
21 
22 logger1.debug('log1 debug')
23 logger2.debug('log2 debug')
24 logger3.debug('log3 debug')
25 '''
26 2017-07-28 22:22:05 PM - root - DEBUG -test:  log1 debug
27 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
28 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test:  log2 debug
29 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
30 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
31 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test:  log3 debug
32 '''
使用
 1 #logging_config.py
 2 LOGGING = {
 3     'version': 1,
 4     'disable_existing_loggers': False,
 5     'formatters': {
 6         'standard': {
 7             'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
 8                       '[%(levelname)s][%(message)s]'
 9         },
10         'simple': {
11             'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
12         },
13         'collect': {
14             'format': '%(message)s'
15         }
16     },
17     'filters': {
18         'require_debug_true': {
19             '()': 'django.utils.log.RequireDebugTrue',
20         },
21     },
22     'handlers': {
23         #打印到终端的日志
24         'console': {
25             'level': 'DEBUG',
26             'filters': ['require_debug_true'],
27             'class': 'logging.StreamHandler',
28             'formatter': 'simple'
29         },
30         #打印到文件的日志,收集info及以上的日志
31         'default': {
32             'level': 'INFO',
33             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
34             'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
35             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
36             'backupCount': 3,
37             'formatter': 'standard',
38             'encoding': 'utf-8',
39         },
40         #打印到文件的日志:收集错误及以上的日志
41         'error': {
42             'level': 'ERROR',
43             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
44             'filename': os.path.join(BASE_LOG_DIR, "xxx_err.log"),  # 日志文件
45             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
46             'backupCount': 5,
47             'formatter': 'standard',
48             'encoding': 'utf-8',
49         },
50         #打印到文件的日志
51         'collect': {
52             'level': 'INFO',
53             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
54             'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
55             'maxBytes': 1024 * 1024 * 5,  # 日志大小 5M
56             'backupCount': 5,
57             'formatter': 'collect',
58             'encoding': "utf-8"
59         }
60     },
61     'loggers': {
62         #logging.getLogger(__name__)拿到的logger配置
63         '': {
64             'handlers': ['default', 'console', 'error'],
65             'level': 'DEBUG',
66             'propagate': True,
67         },
68         #logging.getLogger('collect')拿到的logger配置
69         'collect': {
70             'handlers': ['console', 'collect'],
71             'level': 'INFO',
72         }
73     },
74 }
75 
76 
77 # -----------
78 # 用法:拿到俩个logger
79 
80 logger = logging.getLogger(__name__) #线上正常的日志
81 collect_logger = logging.getLogger("collect") #领导说,需要为领导们单独定制领导们看的日志
事例必须详细看

 

转载于:https://www.cnblogs.com/wcl0517/p/9199221.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值