微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python包的初始与日志模块

什么是包

创建一个aaa的包,自行创建一个__init__py文件

1561980301880

回忆 创建一个tbjx模块发生的三件事:
将该tbjx文件加载到内存.
创建一个以tbjx命名的名称空间.
通过tbjx. 的方式引用tbjx模块的所有的名字.

创建一个包,也会发生三件事:
将该aaa包内 __init__py文件加载到内存.
创建一个以aaa命名的名称空间.
通过aaa. 的方式引用__init__的所有的名字.
包名就是 幕后指使的 init执行

import 方式导入

aaa包与执行文件同级的情况
引用aaa包的__init__中的name
import aaa
print(aaa.name)#因为执行aaa 其实就是执行__inint__中内容


# 我想要引用 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#m1是要引入的文件名 aaa是包名
# 3. 然后在执行文件  aaa.m1.a
# print(aaa.m1.a) 引用 aaa包的m1的a
# print(aaa.m1.func1())#引用 aaa包的m1的func1()


# 如何在当前文件中,引用 aaa包的bbb包中__init__中 name.
# 1. 在执行文件写入 import aaa
# 2. aaa的 __init__ 里面 写 from aaa import bbb
# 3. 然后在执行文件 print(aaa.bbb.name)


# 如何在当前文件中,引用 aaa包的bbb包 a1.py文件中的 name
# 1. 在执行文件写入 import aaa
# 2. 在aaa包的__init__ 写上 from aaa import bbb  (这样写 bbb包的__init__里面所有的名字都能引用)
# 3. 在bbb包的__init__ 写上 from aaa.bbb import mb
4 print(aaa.bbb.a1.name)


# 首先 无论从哪里引用模块,import 或者 from  ... import ...
# 最开始的模块或者包名一定是内存,sys.path中能找到的.(可参考bbb包中的 __init__)
# 直接import 为了让我们会使用 包里面的 __init__

from方式导入 最好用

# 第二类: 执行文件 通过 from ... import... 导入包以及包内的功能
# from ... import ...
# 通过这种方式不用设置__init__文件

我想要引用 aaa包的__init__ name
from aaa import name
print(name)

我想要引用 aaa包的 a1 文件中name
from aaa import a1
print(a1.name)

我想要引用 aaa包的 bbb包 __init__ name
from aaa.bbb import name
print(name)

我想要引用 aaa包的 bbb包 a1文件的中的name
from aaa.bbb import a1
print(a1.name)



重点
# from a.b.c import d
# c的. 的前面一定是包 
# import 的后面一定是名字 可以是文件,并且不能 再有点   不能有点

# from aaa.bbb.m2.func1 import a  # 错误的
# from aaa.bbb import m2
# m2.func1()

相对导入与绝对导入

# from nb.m1 import f1,f2

# from nb.m2 import f3,f4

# from nb.m3 import f5,f6

# 目前为止,今天所看到的引用模块的方式都是绝对导入

# 相对导入: . ..  ......

from .m1 import f1,f2

from .m2 import f3,f4

from .m3 import f5,f6

from .dsb.ly import f7
需求
# 由于nb模块增加了很多很多功能,所以我们nb这个文件就要划整一个包,# 无论对nb模块有任何操作,对于使用者来说不应该改变,极少的改变对其的调用. 像装饰器
第一版 文件变成包了 包与执行文件 在同一目录  
 用户 使用方式
# import nb
# nb.f1()
# nb.f2()
我们的解决方式 在aaa包的__init__ 加入
from nb.m1 import f1,f2#m1 中有f1 f2
from nb.m2 import f3,f4
from nb.m3 import f5,f6

第2版 包与 执行文件 不在同一文件 要想运行 必须在执行文件 添加sys 路径
import sys
sys.path.append(r'D:\python22\python 23 代码\day19\相对导入\第2版 包在另一个文件下\dir') #写死了 可以动态传

第3版 模块改名
在__init__ 里面改成相对导入
from .m1 import f1,f2#当前目录上一级
from .m2 import f3,f4
from .m3 import f5,f6

log日志

工作日志分四个大类:

系统日志:记录服务器的一些重要信息:监控系统,cpu温度,网卡流量,重要的硬件的一些指标,运维人员经常使用的,运维人员,记录操作的一些指令.

网站日志: 访问异常,卡顿,网站一些板块,受欢迎程度,访问量,点击率.等等,蜘蛛爬取次数等等.

辅助开发日志: 开发人员在开发项目中,利用日志进行排错,排除一些避免不了的错误(记录),辅助开发.

记录用户信息日志: 用户的消费习惯,新闻偏好,等等.(数据库解决)

日志: 是谁使用的? 一般都是开发者使用的.

三个版本:

Low版(简易版).

标配版(标准版)
import logging
def log(lj):
    # 创建一个logging对象
    logger = logging.getLogger()

    # 创建一个文件对象
    fh = logging.FileHandler(lj,encoding='utf-8')#传参

    # 创建一个屏幕对象
    sh = logging.StreamHandler()

    # 配置显示格式
    # formatter1变量名
    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(50)#屏幕级别

    logging.debug('调试模式')  # 10
    logging.info('正常模式')  # 20
    logging.warning('警告信息')  # 30
    logging.error('错误信息')  # 40
    # logging.critical('严重错误信息')  # 50
log(r'D:\s23\day19 包的初识 日志模块\day19\日志\标配版日志\aaa\zz.log')

旗舰版(项目中使用的,Django项目) ***

自定制(通过字典的方式)
轮转日志的功能
"""
logging配置
"""

import os
import logging.config

# 定义三种日志输出格式 开始
def load_my_logging_cfg(n):
    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_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+"\log"  # log文件的目录**************************

    logfile_name = '创建课程'+'.log'  # log文件名************** 'all2.lg'

    # 如果不存在定义的日志目录就创建一个
    if not os.path.isdir(logfile_dir):
        os.mkdir(logfile_dir)

    # log文件的全路径 调最外层'handlers'里面
    logfile_path = os.path.join(logfile_dir,logfile_name)

    # log配置字典
    # LOGGING_DIC第一层的所有的键不能更改

    LOGGING_DIC = {
        'version': 1,# 版本号
        'disable_existing_loggers': False,# 固定写法
        'formatters': {
            'standard': {
                'format': standard_format##********绑定上面的3种格式之一对应下面字典 'formatter'
            },#标准的格式
            'simple': {
                'format': simple_format
            },#简单的格式
            'chaojiandan':{'format':id_simple_format},#超简单的格式绑定上面的3种格式之一对应下面字典 'formatter'
        },# 配置格式 上面3个 选其中一个 上面调了 下面也调
        'filters': {},# 固定空字典 过滤模式
        'handlers': {
            # 打印到终端的日志
            'console': {
                'level': 'ERROR',######调级别 5个级别  屏幕显示只要调这个 可以改
                'class': 'logging.StreamHandler',# 打印到屏幕 固定的
                'formatter': 'simple' ##****调屏幕显示格式 可以改 对应'standard'里面的键  'standard' 'simple'
            },# 打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',######调级别5个级别   文件显示只要调这个 可以改
                'class': 'logging.handlers.RotatingFileHandler',# 配置轮转 保存到文件 固定不变
                'formatter': 'standard',###****调文件显示格式 可以改 对应'standard'里面的键  'standard' 'simple'
                'filename': logfile_path,# 日志文件 对应 log文件的全路径  要一一对应
                'maxBytes': 1024*1024*5,# 日志大小 5M 以字节为单位
                'backupCount': 5,#轮转次数
                'encoding': 'utf-8',# 日志文件的编码,再也不用担心中文log乱码了
            },},# 配置 句柄 是文件写入还是屏幕显示
        'loggers': {
            # logging.getLogger(__name__)拿到的logger配置
            '': {
                'handlers': ['default','console'],# 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',#总级别
                'propagate': True,# 向上(更高level的logger)传递
            },# 固定写法
    }


# def load_my_logging_cfg(n):
    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置 固定不变
    logger = logging.getLogger('ATM日志')  # 生成一个log实例
    logger.debug(n)  # 记录该文件的运行状态 比如存钱logger.info(n) 可以配置5个级别???
#[2019-07-06 22:35:37,315][MainThread:11308][task_id:ATM][common.py:104][INFO][11111111]

# if __name__ == '__main__':
#     load_my_logging_cfg(555)
#     pass


# logging.debug('debug message')#10调试模式 括号里面是提示
# logging.info('info message')#20正常模式
# logging.warning('warning message')#30警告模式
# logging.error('error message')#40错误信息 ERROR
# logging.critical('critical message')#50严重错误信息

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐