包以及日志的初识和使用

mac2022-06-30  26

包以及日志的初识和使用

包以及log日志

包的使用

官网解释

Packages are a way of structuring Python’s module namespace by using “dotted module names” 包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

具体的:包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来

需要强调的是:

在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块

import

# 第一类: 执行文件 通过 import 导入包以及包内的功能 # 创建一个aaa的包,自行创建一个__init__py文件 # 回忆 :创建一个tbjx模块发生的三件事: ''' 1. 将该tbjx文件加载到内存. 2. 创建一个以tbjx命名的名称空间. 3. 通过tbjx. 的方式引用tbjx模块的所有的名字. ''' # 创建一个包,也会发生三件事: ''' 1. 将该aaa包内 __init__py文件加载到内存. 2. 创建一个以aaa命名的名称空间. 3. 通过aaa. 的方式引用__init__的所有的名字. ''' import aaa # print(aaa.x) # aaa.f1() # print(aaa.m1) # print(aaa.m1.a) # 我想要引用 aaa包的m1文件的a变量 # 错误示例1: import aaa # 1. aaa的 __init__ 里面 写import m1 # 2. print(aaa.m1.a) # print(aaa.m1.a) # 报错原因: No module named 'm1' # 分析报错原因: 模块找不到 内存,内置,sys.path三个地方找不到. # m1 不在内存,不在内置,sys.path 会主动加载执行文件(包的使用.py)的当前目录. # 解决方式: import aaa # 1. 在执行文件写入 import aaa # 2. aaa的 __init__ 里面 写 from aaa import m1 # 3. 然后在执行文件 aaa.m1.a # print(aaa.m1.a) # aaa.m1.func1() import aaa # 如何在当前文件中,引用 aaa包的bbb包. # 1. 在执行文件写入 import aaa # 2. aaa的 __init__ 里面 写 from aaa import bbb # 3. 然后在执行文件 aaa.bbb # print(aaa.bbb) # 如何在当前文件中,引用 aaa包的bbb包 的 变量 name. # 1. 在执行文件写入 import aaa # 2. aaa的 __init__ 里面 写 from aaa import bbb # 3. 然后在执行文件 aaa.bbb # print(aaa.bbb) import aaa # print(aaa.bbb.name) # 如何在当前文件中,引用 aaa包的bbb包 的 mb文件的函数func. # 1. 在执行文件写入 import aaa # 2. 在aaa包的__Init__ 写上 from aaa import bbb (这样写 bbb包的__init__里面所有的名字都能引用) # print(aaa.bbb.name) # 3. 在bbb包的__Init__ 写上 from aaa.bbb import mb # aaa.bbb.mb.func3() # 首先 无论从哪里引用模块,import 或者 from ... import ... # 最开始的模块或者包名一定是内存,内置,sys.path中能找到的.(可参考bbb包中的 __init__) # 直接import 为了让我们会使用 包里面的 __init__ 第二类: 执行文件 通过 from ... import... 导入包以及包内的功能

from ... import ...

# from ... import ... # 通过这种方式不用设置__init__文件 # from aaa import m1 # m1.func() # from aaa.bbb.m2 import func1 # func1() # from aaa.bbb import m2 # m2.func1() # from a.b.c import d.e.f # c的. 的前面一定是包 # import 的后面一定是名字,并且不能 再有点 # from aaa.bbb.m2.func1 import a # 错误的 # from aaa.bbb import m2 # m2.func1() import json

相对导入与绝对导入

我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

绝对导入:以glance作为起始

相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

在glance/api/version.py #绝对导入 from glance.cmd import manage manage.main() #相对导入 from ..cmd import manage manage.main()

包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的

比如我们想在glance/api/versions.py中导入glance/api/policy.py,有的同学一抽这俩模块是在同一个目录下,十分开心的就去做了,它直接这么做

#在version.py中 import policy policy.get()

没错,我们单独运行version.py是一点问题没有的,运行version.py的路径搜索就是从当前路径开始的,于是在导入policy时能在当前目录下找到

但是你想啊,你子包中的模块version.py极有可能是被一个glance包同一级别的其他文件导入,比如我们在于glance同级下的一个test.py文件中导入version.py,如下

from glance.api import versions ''' 执行结果: ImportError: No module named 'policy' ''' ''' 分析: 此时我们导入versions在versions.py中执行 import policy需要找从sys.path也就是从当前目录找policy.py, 这必然是找不到的 '''

相对导入和绝对导入的总结

绝对导入与相对导入 # 绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入 # 优点: 执行文件与被导入的模块中都可以使用 # 缺点: 所有导入都是以sys.path为起始点,导入麻烦 # 相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入 # 符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹 # 优点: 导入更加简单 # 缺点: 只能在导入包中的模块时才能使用      #注意:         1. 相对导入只能用于包内部模块之间的相互导入,导入者与被导入者都必须存在于一个包内         2. attempted relative import beyond top-level package # 试图在顶级包之外使用相对导入是错误的,言外之意,必须在顶级包内使用相对导入,每增加一个.代表跳到上一级文件夹,而上一级不应该超出顶级包

工作日志分四个大类:

系统日志:记录服务器的一些重要信息:监控系统,cpu温度,网卡流量,重要的硬件的一些指标,运维人员经常使用的,运维人员,记录操作的一些指令.网站日志: 访问异常,卡顿,网站一些板块,受欢迎程度,访问量,点击率.等等,蜘蛛爬取次数等等.辅助开发日志: 开发人员在开发项目中,利用日志进行排错,排除一些避免不了的错误(记录),辅助开发.记录用户信息日志: 用户的消费习惯,新闻偏好,等等.(数据库解决)

日志模块

旗舰版日志 """ logging配置 """ import logging.config # 定义三种日志输出格式 开始 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 定义日志输出格式 结束 logfile_name = 'login.log' # log文件名 logfile_path_staff = r'E:\老男孩学习\JiaoXueJiHua\day19\day19\日志模块\staff.log' logfile_path_boss = r'E:\老男孩学习\JiaoXueJiHua\day19\day19\日志模块\boss.log' logfile_path_login = r'E:\老男孩学习\JiaoXueJiHua\day19\day19\日志模块\login.log' # log配置字典 # LOGGING_DIC第一层的所有的键不能改变 LOGGING_DIC = { 'version': 1, # 版本号 'disable_existing_loggers': False, # 固定写法 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, 'id_simple':{ 'format': id_simple_format } }, 'filters': {},#过滤 'handlers': { #打印到终端的日志 'sh': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'id_simple' }, #打印到文件的日志,收集info及以上的日志 'fh': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', 'filename': logfile_path_staff, # 日志文件 'maxBytes': 5000, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, 'boss': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'id_simple', 'filename': logfile_path_boss, # 日志文件 'maxBytes': 5000, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { #logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['sh', 'fh', 'boss'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 }, }, } def md_logger(): logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置 logger = logging.getLogger("login.log") # 生成一个log实例 return logger logger.debug('It works!') # 记录该文件的运行状态 dic = { 'username': '小黑' } def login(): # print('登陆成功') md_logger().info(f"{dic['username']}登陆成功") # # def aricle(): # print('欢迎访问文章页面') login() # aricle()

Low版(文件与屏幕输入只能选择一个)

# import logging # logging.basicConfig( # level=logging.DEBUG, # ) # # logging.debug('debug message') # # logging.info('info message') # # logging.warning('warning message') # # logging.error('error message') # # logging.critical('critical message') # 应用: # def func(): # print('in func') # logging.debug('正常执行') # func() # try: # i = input('请输入选项:') # int(i) # except Exception as e: # logging.error(e) # print(11) # low版的日志:缺点: 文件与屏幕输入只能选择一个. import logging logging.basicConfig( # level=logging.DEBUG, level=30, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', filename=r'test.log', ) # logging.debug('调试模式') # 10 # logging.info('正常模式') # 20 logging.warning('警告信息') # 30 # logging.error('错误信息') # 40 # logging.critical('严重错误信息') # 50

标配版日志(文件和屏幕)

# import logging # # # 创建一个logging对象 # logger = logging.getLogger() # # # 创建一个文件对象 # fh = logging.FileHandler('标配版.log', encoding='utf-8') # # # 创建一个屏幕对象 # sh = logging.StreamHandler() # # # 配置显示格式 # formatter1 = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s') # formatter2 = logging.Formatter('%(asctime)s %(message)s') # fh.setFormatter(formatter1) # sh.setFormatter(formatter2) # # logger.addHandler(fh) # logger.addHandler(sh) # # # 总开关 # logger.setLevel(10) # # fh.setLevel(10) # sh.setLevel(40) # # logging.debug('调试模式') # 10 # logging.info('正常模式') # 20 # logging.warning('警告信息') # 30 # logging.error('错误信息') # 40 # logging.critical('严重错误信息') # 50 posted on 2019-07-01 20:36  七橼77 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/-777/p/11116580.html

最新回复(0)