• 20反射、md5加密、以及日志模块logging(复习)


    1、反射

      关键字:  

        getattr 根据字符串的形式,去对象中找该成员
        hasattr 根据字符串的形式,判断对象中是否有该成员
        setattr 根据字符串的形式,去对象动态设置一个成员(内存)
        delattr 根据字符串的形式,去判断对象动态的设置一个成员(内存)

      简单例子:

        1、在handler文件中定义五个函数及一个数字

    def f1():
        print("F1")
    def f2():
        print("F2")
    def f3():
        print("F3")
    def f4():
        print("F4")
    def f5():
        print("F5")
    
    f0 = 9

        2、然后新建一个run文件。根据input的数字去调对应的函数

    from types import FunctionType
    import handler
    while True:
        print("""
        系统支持的函数有:
            1.f1
            2.f2
            3.f3
            4.f4
            5.f5
            6.f6
        """)
        val = input("请输入要执行的函数:")
        if hasattr(handler, val):    # 判断是否输入正常
            func_or_val = getattr(handler, val)  # 根据字符串为参数,去模块中寻找与之同名的成员
            if isinstance(func_or_val, FunctionType):
                func_or_val()
            else:
                print(func_or_val)
        else:
            print('不存在输入的属性名')
    # 总结。根据字符串为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员

      当数据量比较庞大时,不可能写一堆的判断,此时反射就显得尤为重要。 

      总结:

        什么是反射:以字符串为参数(第二个参数),去对象中(第一个参数)找与之同名的成员(一句话概括:通过字符串的形式操作对象相关的属性)

    2、md5加密

      在python中md5加密依赖于hashlib模块

      平常的md5加密,很容易被撞库破解。这时候需要加盐。

      简单例子如下:

    import hashlib
    SALT = b'asdasd'
    
    
    def md5(pwd):
        obj = hashlib.md5(SALT)   # 加盐 SALT
        obj.update(pwd.encode('utf-8'))
    
        # 获取密文
        v = obj.hexdigest()
        return v

      # 由于md5是不可逆的,所以md5的解密。是拿已加密的数据和明文加密的数据进行比对,从而得出结论。

    3、日志。

      日志用到的是python的logging模块。简单例子如下:

    import logging
    
    logger = logging.basicConfig(filename='xx.text',
                                 format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
                                 datefmt='%Y-%m-%d %H:%M:%S',
                                 level=30)
    
    def func():
        try:
            a = a + 1
        except Exception as  e:
            logging.error(e)
    
    
    func()

      打印结果如下:

    2019-07-23 11:11:37 - root - ERROR - 日志: local variable 'a' referenced before assignment

      此时,我们是使用的原生的logging,局限性太多,如所有的日志都会存在一个文件。然后我们重新写一个。

    # coding:utf-8
    import logging, time
    import os
    # log_path是存放日志的路径
    cur_path = os.path.dirname(os.path.realpath(__file__))
    log_path = os.path.join(os.path.dirname(cur_path), 'logs')
    # 如果不存在这个logs文件夹,就自动创建一个
    if not os.path.exists(log_path):os.mkdir(log_path)
    
    
    class Log():
        def __init__(self):
            # 文件的命名
            self.logname = os.path.join(log_path, '%s.log'%time.strftime('%Y_%m_%d'))
            self.logger = logging.getLogger()
            self.logger.setLevel(logging.DEBUG)
            # 日志输出格式
            self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s')
    
        def __console(self, level, message):
            # 创建一个FileHandler,用于写到本地
            # fh = logging.FileHandler(self.logname, 'a')  # 追加模式  这个是python2的
            fh = logging.FileHandler(self.logname, 'a', encoding='utf-8')  # 这个是python3的
            fh.setLevel(logging.DEBUG)
            fh.setFormatter(self.formatter)
            self.logger.addHandler(fh)
    
            # 创建一个StreamHandler,用于输出到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)
            ch.setFormatter(self.formatter)
            self.logger.addHandler(ch)
    
            if level == 'info':
                self.logger.info(message)
            elif level == 'debug':
                self.logger.debug(message)
            elif level == 'warning':
                self.logger.warning(message)
            elif level == 'error':
                self.logger.error(message)
            # 这两行代码是为了避免日志输出重复问题
            self.logger.removeHandler(ch)
            self.logger.removeHandler(fh)
            # 关闭打开的文件
            fh.close()
    
        def debug(self, message):
            self.__console('debug', message)
    
        def info(self, message):
            self.__console('info', message)
    
        def warning(self, message):
            self.__console('warning', message)
    
        def error(self, message):
            self.__console('error', message)

      然后使用的时候配合traceback模块(需先导入)。

        def func(self):
            try:
                a = a + 1
            except Exception as  e:
                # 获取当前错误的堆栈信息
                msg = traceback.format_exc()
                self.log.error(msg)
                return '500'

      日志结果为:

      

      

      此时,一个完整的日志处理模块就完成了(后续还可以按照等级,分不同的文件),不过后面的开发框架都已经有很完善的了。这里就不过多赘述了。

      

      

      

  • 相关阅读:
    vTiger 5.2+ 语言包安装教程
    linux iconv方法的使用
    php XMLWriter类的简单示例
    DIV+CSS网站导航条
    php同步方案
    PHP区间分页
    phpcms2008添加上一篇下一篇的功能
    Yii框架整合Ucenter更新与增强
    Linux openSUSE / CentOS / Slackware / Gentoo
    project mail
  • 原文地址:https://www.cnblogs.com/cbslock/p/11230555.html
Copyright © 2020-2023  润新知