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()
      
      
原文地址:https://www.cnblogs.com/yaoqi17/p/11133982.html