zoukankan      html  css  js  c++  java
  • python之包及logging日志

    一、包的使用

    1. 定义

      ​ 当一个模块中包含的函数特别多时,我们需要将py文件分成多个文件放在一个文件夹中,这个文件夹中包含有多个py文件,将这个文件夹叫做包。

    2. 使用方法

      • import

        执行文件通过import导入包以及包内的功能

        创建一个包同样会发生三件事:

        1. 将该aaa包内__init__py文件加载到内存
        2. 创建一个以aaa命名的名称空间
        3. 通过aaa.的方式引用__init__的所有名字
        • 在包的使用.py文件中引用aaa包中的m1的a变量

        • 在包的使用.py文件中引用aaa包中的bbb包的mb.py的func函数

        总结:首先无论从哪里引用模块,import 或者 from ... import ...,最开始的模块或者包名一定是内存,内置,sys.path中能找到的.(可参考bbb包中的 __init__)

      • from...import...

        通过这种方式不用设置__init__文件

        • 在包的使用.py文件中引用aaa包中的m1的a变量

          from aaa import m1
          m1.a
          
        • 在包的使用.py文件中引用aaa包中的bbb包的mb.py的func函数

          from aaa.bbb.mb import func
          func()
          # 或者
          from aaa.bbb import mb
          mb.func()
          

        总结:from a.b.c import d.e.f c 的. 的前面一定是包import 的后面一定是名字,并且不能再有点

    3. 绝对导入与相对导入

      在包的内部也有彼此之间相互导入的需求,这个时候就有绝对导入和相对导入两种方式

      • 绝对导入:以顶级包为起始(之前用的基本都是绝对导入)
      • 相对导入:用.或者..的方式作为起始(只能在一个包中使用,不能用于不同目录内)

      在执行文件中引用bbb包的m2的func1函数,func1函数中又引用了aaa中的m3中的func2

      总结:

      • 绝对导入:以执行文件的sys.path为起点开始导入,称之为绝对导入

        优点:执行文件与被导入的模块中都可以使用

        缺点:所有导入都是以sys.path为起点,导入麻烦

      • 相对导入:参照当前所在的文件的文件夹为起始开始查找,称之为相对导入

        符号:.代表当前所在文件的文件夹,..代表上一级文件夹

        优点:导入更加简单

        缺点:只能再导入包中的模块时才使用

        注意:1.相对导入只能用于包内部模块之间的相互导入,导入者与被导入这都必须存在于一个包内。2.attempted relative import beyond top-level package # 试图在顶级包之外使用相对导入是错误的,言外之意,必须在顶级包内使用相对导入,每增加一个.代表跳到上一级文件夹,而上一级不应该超出顶级包

    二、logging日志

    1. 分类

      工作日志分四个大类:

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

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

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

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

    2. 三个版本

      • 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
        
      • 旗舰版(Django项目)

        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:python_workspaceday019顶配版staff.log'
        logfile_path_boss = r'E:python_workspaceday019oss.log'
        
        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'
                },
                'fh': {
                    'level': 'DEBUG',
                    'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                    'formatter': 'standard',
                    'filename': logfile_path_staff,  # 日志文件
                    'maxBytes': 300,
                    'backupCount': 5,
                    'encoding': 'utf-8',
                },
                'boss': {
                    'level': 'DEBUG',
                    'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                    'formatter': 'id_simple',
                    'filename': logfile_path_boss,  # 日志文件
                    'maxBytes': 300,
                    'backupCount': 5,
                    'encoding': 'utf-8',
                }
            },
            'loggers': {
                # logging.getlogger(__name__)拿到logger配置
                '': {
                    'handlers': ['sh', 'fh', 'boss'],  # 把上面定义的两个handle都加上,即log数据既写入文件有打印到屏幕
                    'level': 'DEBUG',
                    'propagate': True,  # 向上(更高level的logger)传递
                }
            }
        }
        
        
        def md_logger():
            logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
            logger = logging.getLogger()  # 生成一个log实例
            return logger
        
        
        dic = {
            'username': '小黑'
        }
        
        
        def login():
            md_logger().info(f"{dic['username']}登陆成功")
        
        
        login()
        
        
  • 相关阅读:
    cookie和session的区别
    PHP中require和include的区别
    设计模式之建造者模式
    设计模式之抽象工厂模式
    设计模式之工厂模式
    HTTPS为什么是安全的?
    设计模式之单例模式(Singleton Pattern)
    设计模式(Design Patterns)
    Linux命令:awk
    Nginx与PHP如何协同工作
  • 原文地址:https://www.cnblogs.com/yaoqi17/p/11133982.html
Copyright © 2011-2022 走看看