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'

  日志结果为:

  

  

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

  

  

  

原文地址:https://www.cnblogs.com/cbslock/p/11230555.html