约束,自定义异常,hashlib,logging

时间:2024-01-21 12:06:20

一丶约束

建议使用:   

class BaseMessage(object):
    def send(self):
    """
    必须继承BaseMessage,然后其中必须编写send方法。
        用于完成具体业务逻辑。
    """
            raise NotImplementedError(".send() 必须被重写.")
        # raise Exception(".send() 必须被重写.")        

主动抛出异常的方法,BaseMessage类用于约束,约束其派生类,保证派生类中必须编写send方法,不然执行可能会报错

class BaseMessage(object):
    def send(self,x1):
        """
        必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
        """
        raise NotImplementedError(".send() 必须被重写.")

class Email(BaseMessage):
    def send(self,x1):
        """
        必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
        """
        pass


obj = Email()
obj.send(1)
具体应用

 

抽象和抽象类方法:

from abc import ABCMeta,abstractmethod


class Base(metaclass=ABCMeta): # 抽象类

    def f1(self):
        print(123)


    @abstractmethod
    def f2(self):   # 抽象方法
        pass

class Foo(Base):

    def f2(self):
        print(666)


obj = Foo()
obj.f1()
抽象类和抽象方法

 

关于其他语言(c#,java):

  抽象类抽象方法约束: 

abstact class Foo:
                        def f1(self):
                            print(1,3,4) 
                            
                        abstact def f2(self):pass
                    
                    class Bar(Foo):
                        def f2(self):
                            print('111')
                            
伪代码

  关于接口约束:

                                 interface IFoo:
                    
                    def f1(self,x1):pass 
                    
                    def f2(self,x1):pass 
                    
                interface IBar:
                    
                    def f3(self,x1):pass 
                    
                    def f4(self,x1):pass 
                
                class Foo(IFoo,IBar):# 实现了2个接口
                    
                    def f1(self,x1):pass 
                    
                    def f2(self,x1):pass 
                    
                    def f3(self,x1):pass 
                    
                    def f4(self,x1):pass                 
伪代码

总结:

1.什么是接口以及作用?

  接口是一种数据类型,主要用于约束派生类中必须实现指定的方法.

  python中不存在,(java,c#中有)

2.python中使用什么来约束?

  抽象类-抽象方法 编写麻烦

  人为主动抛出异常

3.结束时,抛出异常是否可以用其他的?

  不专业: raise Exception(".send() 必须被重写")

  专业:raise NotImplentedError(".send()  必须被重写.")

4.应用场景

  多个类,内部都必须有某种方法的时候,需要使用基类+异常抛出进行约束

  学院管理系统:

 

                    class IBase:
                        def login():
                            raise NotImplementedError(".send() 必须被重写.")
                    
                    class Student:
                        def login(self):
                            pass 
                            
                        def score(self):
                            pass 
                            
                    class Teacher:
                        def login(self):
                            pass 
                            
                        def exam(self):
                            pass 
                            
                    class Manager(self):
                        def login(self):
                            pass 
                            
                        ....
伪代码

 


二丶自定义异常
# 知识点:如何自定义异常类?
class MyException(Exception):
    def __init__(self,code,msg):
        self.code = code
        self.msg = msg
try:
    # 知识点:主动抛出异常 
    raise MyException(1000,'操作异常')

except KeyError as obj:
    print(obj,1111)
except MyException as obj: # 知识点:捕获异常 
    print(obj,2222)
except Exception as obj:
    print(obj,3333)
实例

 

 

 三丶hashlib (加密)

import hashlib

SALT = b'2erer3asdfwerxdf34sdfsdfs90'

def md5(pwd):
    # 实例化对象
    obj = hashlib.md5(SALT)
    # 写入要加密的字节
    obj.update(pwd.encode('utf-8'))
    # 获取密文
    return obj.hexdigest() # 21232f297a57a5a743894a0e4a801fc3 # 66fbdc0f98f68d69cd458b0cee975fe3 # c5395258d82599e5f1bec3be1e4dea4a


user = input("请输入用户名:")
pwd = input("请输入密码:")
if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a':
    print('登录成功')
else:
    print('登录失败')
hashlib
用于加密相关的操作,代替了md5模块和sha模块,主要提供
SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法.
import hashlib

# ######## md5 ########
hash = hashlib.md5()
# help(hash.update)
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
print(hash.digest())

######## sha1 ########

hash = hashlib.sha1()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())

# ######## sha256 ########

hash = hashlib.sha256()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())

# ######## sha384 ########

hash = hashlib.sha384()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())

# ######## sha512 ########

hash = hashlib.sha512()
hash.update(bytes('admin', encoding='utf-8'))
print(hash.hexdigest())
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。


import hashlib

# ######## md5 ########

hash = hashlib.md5(bytes('898oaFs09f', encoding="utf-8"))
hash.update(bytes('admin', encoding="utf-8"))
print(hash.hexdigest())
各种加密算法

python 内置还有一个 hmac模块,他内部对我们创建的key和内容进行进一步处理然后加密

import hmac

h = hmac.new(bytes('898oaFs09f', encoding="utf-8"))
h.update(bytes('admin', encoding="utf-8"))
print(h.hexdigest())
hmac

 

四丶logging  (日志)

1.单文件日志

import logging

logger = logging.basicConfig(filename='xxxxxxx.txt',
                             format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                             datefmt='%Y-%m-%d %H:%M:%S',
                             level=30)

logging.debug('x1') # 10
logging.info('x2')  # 20
logging.warning('x3') # 30
logging.error('x4')    # 40
logging.critical('x5') # 50
logging.log(10,'x6')
日志
import traceback

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

注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。

日志格式:

 

2.多文件日志

 对于上述记录日志的功能,只能将日志文件记录到单文件中,如果想设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件 和 日志操作文件

# 定义文件
file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
file_1_1.setFormatter(fmt)

file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
fmt = logging.Formatter()
file_1_2.setFormatter(fmt)

# 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1)
logger1.addHandler(file_1_2)


# 写日志
logger1.critical('1111')
日志一
# 定义文件
file_2_1 = logging.FileHandler('l2_1.log', 'a')
fmt = logging.Formatter()
file_2_1.setFormatter(fmt)

# 定义日志
logger2 = logging.Logger('s2', level=logging.INFO)
logger2.addHandler(file_2_1)
日志(二)
  • 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
  • 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中

实例:

import logging


# 创建一个操作日志的对象logger(依赖FileHandler)
file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))

logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_handler)


logger1.error('123123123')



# 在创建一个操作日志的对象logger(依赖FileHandler)
file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s"))

logger2 = logging.Logger('s2', level=logging.ERROR)
logger2.addHandler(file_handler2)

logger2.error('666')
...