1.今日内容
- 包
- logging模块
2.具体内容
-
包
-
对于一个内容较多的模块,模块本身遵循软件开发规范。因此,如需要调用模块,本质上需要调用这个文件夹,称之为包
-
具体:包就是一个包含有
__init__
文件的文件夹 -
创建一个包发生的三件事:
- 将包内的
__init__
.py文件加载到内存 - 创建一个以包名称而命名的名称空间
- 通过.包的方式,引用
__init__
.py的所有名字
- 将包内的
-
第一类调用:直接import
- 引用包中的py文件
- 需查看路径,是否在内存,内置函数,sys.path中,并根据当前目录来观察包是否可以调用
- example:引用包qqq内的s1文件的变量a:
- 在执行文件中写入:
import aaa
- 在包qqq的
__init__
.py中写入:from qqq import s1
- 在执行文件中调用:
qqq.s1.a
- 在执行文件中写入:
- 注意:sys.path会在编译过程开始时,主动加载执行文件的当前目录,因此,可以从执行文件的父级目录出发,寻找包,进而操作
__init__
- 引用包中的py文件
-
第二类调用:from...import...:
- 这种方式不需要设置
__init__
文件 - 一般形式:
from a.b.c import d
:- c的.前面一定是包,import后一定是名字(文件,变量,函数,类,对象等),并且不能在有点
- 这种方式不需要设置
-
相对导入与绝对导入
- 绝对导入:以执行文件的sys.path为起始点开始导入
- 执行文件被导入的模块中都可以使用
- 但所有导入都是以sys.path为起始点,导入麻烦
- 相对导入:参照当前所在文件的文件夹为起始开始查找
- 只能在导入包中的模块时才能使用
- 注意⚠️:相对导入只能用于包内部模块之间的相互导入,导入者与被导入者都必须存在与一个包中;每增加一个.代表跳到上一级文件夹,而上一级不应该超出顶级包。
#绝对导入 from qqq.s1 import a #相对导入 from ..s1 import a
- 绝对导入:以执行文件的sys.path为起始点开始导入
-
-
logging模块
- 简单模式
import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
- 灵活模式
import os 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_sraff = 'staff.log' logfile_path_boss = 'boss.log' #log文件的目录 #logfile_dir = os.path.dirname(os.path.abspath(__file__)) #logfile_name = 'a.log' #log文件名 #如果不存在定义的日志目录就创建一个 #if not os.path.isdir(logfile_dir): # os.mkdir(logfile_dir) #log文件的全路径 #logfile_path = os.path.join(logfile_dir, logfile_name) #log配置字典 #LOGGING_DIC第一层的所有的键不能改变 LIOGGING_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_sraff, #日志文件 'maxBytes':1024*1024*5, #日志大小 5M 'backupCount':5, 'encoding':'utf-8', #日志文件的编码, }, 'boss':{ 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter':'id_simple', 'filename':logfile_path_boss, # 'maxBytes':500, 'backupCount':5, 'encoding':'utf-8', } }, 'loggers':{ # logging.getLogger(__name__)#拿到logger配置 '':{# 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'handlers':['sh','fh','boss'], 'level':'DEBUG', 'propagate':True,#向上(更高level的logger)传递 } } } def md_logger(): logging.config.dictConfig(LIOGGING_DIC)#导入上面定义的logging配置 logger = logging.getLogger()#生成一个log实例 return logger dic = { 'username':'小黑' } def login(): md_logger().info(f"{dic['username']}登陆成功") login()