day 26 约束、自定义异常、加密hashlib、logging

一、约束

建议使用:
class BaseMessage(object):
    def send(self):
        """
        必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
        """
        raise NotImplementedError(".send() 必须被重写.")  主动抛异常,意味着子类中必须有send方法

#BaseMessage类用于约束,约束其派生类:保证派生类中必须编写send方法,不然执行可能就会报错。
 1 class BaseMessage(object):
 2     def send(self):
 3         """
 4         必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
 5         """
 6         raise Exception()
 7 
 8 class Email(BaseMessage):
 9     def send(self):
10         pass # 发送邮件
11         
12     def f1(self):
13         pass 
14     
15     def f2(self):
16         pass 
17 class Wechat(BaseMessage):
18     def send(self):
19         pass # 发送微信
20     
21     def f1(self):
22         pass 
23     
24     def f2(self):
25         pass 
26 class Msg(BaseMessage):
27     def send(self):
28         pass # 发送短信
29         
30     def f1(self):
31         pass 
32     
33     def f2(self):
34         pass 
35         
36         
37 def func(arg):
38     """
39     报警通知的功能
40     """
41     arg.send()
42     
43 
44 obj = Msg()
45 func(obj)
约束实例一
 1 class BaseMessage(object):
 2     def send(self,x1):
 3         """
 4         必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
 5         """
 6         raise NotImplementedError(".send() 必须被重写.")
 7 
 8 class Email(BaseMessage):
 9     def send(self,x1):
10         """
11         必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。
12         """
13         pass
14 
15 obj = Email()
16 obj.send(1)   #中有几个参数,子类中的send方法中必须有相同的参数
约束实例二
 1 Python:
 2  3     类:
 4         class Foo:
 5             pass 
 6     抽象类和抽象方法:
 7         
 8 Java、C#:
 9 10 11         class Foo:
12             def f1(self):
13                 pass 
14                 
15             def f2(self):
16                 pass # 可人为抛出异常。 
17                 
18         class Bar(Foo):
19             def f1(self):
20                 pass 
21     
22     抽象类,约束,约束继承它的派生类必须实现它其中的抽象方法。
23         abstact class Foo:
24             def f1(self):
25                 print(1,3,4) 
26                 
27             abstact def f2(self):pass
28         
29         class Bar(Foo):
30             def f2(self):
31                 print('111')
32                 
33         
34         
35 接口,接口中不允许在方法内部写代码,只能约束继承它的类必须实现接口中定义的所有方法。
36     interface IFoo:
37         
38         def f1(self,x1):pass 
39         
40         def f2(self,x1):pass 
41         
42     interface IBar:
43         
44         def f3(self,x1):pass 
45         
46         def f4(self,x1):pass 
47     
48     class Foo(IFoo,IBar):# 实现了2个接口
49         
50         def f1(self,x1):pass 
51         
52         def f2(self,x1):pass 
53         
54         def f3(self,x1):pass 
55         
56         def f4(self,x1):pass 
java中的接口和python对比
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()
python中的抽象类和抽象方法 了解
总结:
1. 什么是接口以及作用?
  接口时一种数据类型,主要用于约束派生类中必须实现指定的方法。
  Python中不存在,Java和C# 中是存在的。
2. Python中使用过什么来约束呢?
  - 抽象类+抽象方法(伪造出接口类型),编写上麻烦。
  - 人为主动抛出异常 

3. 约束时,抛出的异常是否可以用其他的?
  不专业:raise Exception(".send() 必须被重写.")
  专业:raise NotImplementedError(".send() 必须被重写.")

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

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


obj = Email()
obj.send(1)


6. 应用场景:
多个类,内部都必须有某些方法时,需要使用基类+异常进行约束。
学员管理程序:

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: # 知识点:捕获异常   结果#(1000, '操作异常') 2222
    print(obj,2222)
except Exception as obj:
    print(obj,3333)
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)
例子

  

  二、加密

import hashlib   引入模块
SALT = b'2erer3asdfwerxdf34sdfsdfs90'
def md5(pwd):
    # 实例化对象
    obj = hashlib.md5(SALT)     #SALT为加盐操作,加入特殊的值,防止别人盗用
    # 写入要加密的字节
    obj.update(pwd.encode('utf-8'))   #要加密的必须是字节,字符串用encode来转化为字节
    # 获取密文
    return obj.hexdigest() #  c5395258d82599e5f1bec3be1e4dea4a

user = input("请输入用户名:")
pwd = input("请输入密码:")
if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a':
    print('登录成功')
else:
    print('登录失败')

  三、日志

    日志的目的是为了给开发着看的,当有错误时,把错误记录下来。防止发生错误的时候开发者方便排查错误

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()

实例坑:

引入模块只能导入一个日志,有两个及以上是,内存中只会存在第一个文件

import logging

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

logging.error('x4')
logging.error('x5')
View Code

自定义日志可以解决上述问题

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')
View Code
原文地址:https://www.cnblogs.com/xiaobai686/p/11765655.html