什么是包?

  它是一系列模块文件的集合体,表现形式就是一个文件夹

  内部通常都会有一个__init__.py文件

  包的本质还是一个模块

为什么要使用包?

  包的本质是一个文件夹形式的模块,他的唯一功能就是将文件组织起来,随着功能越写越多,我们不可能将所有功能都放在一个py文件中,于是我们使用模块来组织功能,随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性

首次导入包发生的三件事

  先产生一个执行文件的名称空间,导入包

    1.先创建包下面的__init__.py文件的名称空间

    2.执行包下面的__init__.py文件的代码,将产生的名字存放在__init__.py文件的名称空间中

    3.在执行文件中拿到一个指向包下面__init__.py文件的名称空间的名字

绝对导入和相对导入的选用:

  当作为包的设计者来说

  1.当模块的功能很多的情况下,应该分文件管理

  2.每个模块之间为了避免后期模块改名的问题,需要使用相对导入(包里的文件都应该是可导入的模块)

绝对路径和相对路径的选用:

  站在包的开发者:如果使用绝对路径来管理自己的模块,它只需永远以包的路径为基准依次导入模块

  站在包的使用者:必须将包所在的文件夹路径添加到system path中

1 # 包中的代码块
2 from day1701.p1 import p2  # 导入p2这个包,从p2里的__init__拿数据
3 p2.f1()  # p2包中根据已导入的模块取出函数f1
4 p2.f3()  # p2包中根据已导入的模块取出函数f3
1 # __init__.py文件中的模块导入代码块
2 from day1701.p1.p2.m1 import f1  # 绝对导入,以执行文件的位置为准
3 from .m3 import f3  # 相对导入,以该文件的位置为基准

包和常用内置模块(二)  包和常用内置模块(二)

需要注意的是:在导入语句中 .号的左边肯定是一个包(文件夹)

python2和python3中的区别

  python2如果要导入包,包下面必须要有__init__文件

  python3如果要导入包,包下面没有__init__文件也不会报错

  所以我们在删除文件的时候不能把__init__文件删除,哪怕是他里边没有内容

 

2.logging模块

日志模块:用来记录程序运行信息的模块

日志模块的等级

 1 # logging日志模块
 2 import logging
 3 logging.basicConfig(filename='access.log',
 4                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
 5                     datefmt='%Y-%m-%d %H:%M:%S %p',
 6                     level=30
 7                     )
 8 # 日志模块的等级
 9 logging.debug('debug日志')  # 10
10 logging.info('info日志')  # 20
11 logging.warning('warning日志')  # 30
12 logging.error('error日志')  # 40
13 logging.critical('critical日志')  # 50
14 # 等级由上到下越来越高

包和常用内置模块(二)

需要解决三个问题

  1.乱码

  2.日志格式问题

  3.如何既打印到终端又写到文件中

 

输出日志的八个步骤

 1 import logging
 2 # 1.logger对象:负责产生日志
 3 logger = logging.getLogger('转账记录')
 4 
 5 # 2.filter对象:过滤日志(了解)
 6 
 7 # 3.handler对象:控制日志输出的位置(文件或者终端)
 8 hd1 = logging.FileHandler('a1.log',encoding='utf-8')  # 输出到文件
 9 hd2 = logging.StreamHandler()  # 输出到终端
10 
11 # 4.formatter对象:规定日志内容的格式
12 fm1 = logging.Formatter(
13     fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
14     datefmt='%Y-%m-%d %H:%M:%S %p'
15 )
16 fm2 = logging.Formatter(
17     fmt='%(asctime)s - %(name)s :  %(message)s',
18     datefmt='%Y-%m-%d'
19 )
20 
21 # 5.给logger对象绑定handler对象
22 logger.addHandler(hd1)
23 logger.addHandler(hd2)
24 
25 # 6.给handler绑定formatter对象
26 hd1.setFormatter(fm1)
27 hd2.setFormatter(fm2)
28 
29 # 7.设置日志等级
30 logger.setLevel(10)
31 
32 # 8.记录日志
33 logger.debug('这边出了问题,来看一下')

输出到文件的效果

包和常用内置模块(二)

输出到终端的效果

包和常用内置模块(二)

对象之间的互相使用

包和常用内置模块(二)

 

logging配置字典(*****)

配置字典提供了一种快速生成日志的方式,可以使用该模块

# 日志字典的格式,可以直接复制
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'


# 定义日志输出格式 结束
"""
下面的两个变量对应的值 需要我们手动修改
"""
logfile_dir = os.path.dirname(__file__)  # log文件的目录
logfile_name = 'a3.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 = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},  # 过滤日志
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        '': {  # 当键不存在的情况下 默认都会使用该k:v配置
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },
    },
}

# 使用日志字典配置,这个也需要自己配置
logging.config.dictConfig(LOGGING_DIC)  # 自动加载字典中的配置
logger1 = logging.getLogger('记录')
logger1.debug('日志字典配置的使用')
日志字典的模版

相关文章: