1、类的约束
 
    1、写一个父类,父类中的某个方法要抛出一个异常 NotImplementedError
class Base:
    # 对子类进行了约束,必须重写该方法
    def login(self):
        # 没有被实现错误
        raise NotImplementedError('请重写login这个方法')  # 抛异常

class Nomal(Base):
    def login(self):
        pass

class Member(Base):
    def login(self):
        pass

class Admin(Base):
    def denglu(self):  # 报错,上层程序员没有按照规范来写代码
        pass

# 项目经理写的总入口,整合这些功能
def login(obj):
    print('准备验证码...')
    obj.login()
    print('进入主页...')

n = Nomal()
m = Member()
a = Admin()
login(n)
login(m)
login(a)  # 报错
View Code

2、抽象类和抽象方法

from abc import ABCMeta, abstractmethod
class Base(metaclass = ABCMeta):
    @abstractmethod
    def fangfa(self):
        pass

 

# 抽象方法不需要给出具体的方法体,抽象方法内只写一个pass就可以了
# 在一个类中如果一个方法是抽象方法,那么这个类就一定是抽象类
# 在抽象类中,如果有抽象方法,此时这个类不能创建对象
# 如果一个类中所有的方法都是抽象方法,这个类可以被称为接口类

# 写一个抽象方法:导入一个模块
from abc import ABCMeta, abstractmethod

# 此时抽象类不能创建对象
class Animal(metaclass = ABCMeta):
    @abstractmethod #抽象方法
    def eat(self): pass

    # 抽象类中可以有正常的方法
    def run(self):
        print('')

# 子类必须实现父类中的抽象方法,否则子类也是抽象类,抽象类不能创建对象
# class Cat(Animal): # 此时猫里面也有一个抽象方法,此时的猫是创建不了对象的
#     pass

class Cat(Animal):
    def eat(self):
        print('猫喜欢吃鱼')

a = Cat()
a.eat()
a.run()
    总结:约束,其实就是父类对子类进行约束,子类必须要写***方法
 
    1、使用抽象类和抽象方法,由于该方法的来源是java和c#,所以使用频率还是很少的
    2、使用人为抛出异常的方案,并且精良抛出的是NotImplementedError,这样比较专业,而且错误比较明显。
 
2、异常处理  try except raise
#常用异常
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
异常是程序在运行过程中产生的错误,语法上的错误跟异常处理无关,必须在程序运行前就修正.
if判断式的异常处理
 
if判断式的异常处理只能针对某一段代码,对于不同代码段的相同类型的错误,则需要写重复的if判断,在程序中频繁的写鱼程序本身无关,与异常处理有关的if,可读性及其差。
try:
    代码
except 异常类:
    出了错,如何处理异常
except 异常类:
    出了错,如何处理异常
except 异常类:
    出了错,如何处理异常

else:
    当程序不出错
finally:
    不管出不出错都要执行
try:
    print(1/0)
    f = open("哈哈", mode = 'r')
    d = {[]:123}
except ZeroDivisionError:  
    print('除以0出错了')
except FileNotFoundError:
    print('文件不存在的错误')
except Exception:  # 兜底的
    print('其他错误')
else: # 当try中的代码不产生任何错误的时候,会自动地执行else里的代码
    pass
finally:# 最终,不管出错,还是不出错,都要执行最后的finally,一般用来收尾
    print('哈哈哈哈哈')
raise 异常类(“信息”)
 
如何自己定义异常
class 类(Exception):
    pass
# 如何自己定义异常
# 随便写一个类,这个类只要继承类Exception,这个类就是一个异常类,可以作为raise对象
class CulException(Exception):
    pass

def cul(a,b):
    # 只能是数字相加

    if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
        return a+b
    else:
        # 抛出异常
        # raise 异常类(错误信息)
        raise CulException("无法处理这样的运算")

print(cul('aa',2))
堆栈  (错误信息叫堆栈信息)
import traceback
traceback.format_exc()
 
#  会员买东西
import traceback  # 用来查看堆栈信息

class MemberException(Exception):
    pass

class Person:
    def __init__(self,name,ismember):
        self.name = name
        self.ismember = ismember

    def buy(self):
        print(f"{self.name}在买东西")

def place(ren):
    if ren.ismember == '是会员':
        ren.buy()
    else:
        raise MemberException("不是会员,快去办会员吧")

try:
    p1 = Person('zhangmeng','是会员')
    p2 = Person('zhouyou','不知道')
    place(p1)
    place(p2)
except MemberException:
    ret = traceback.format_exc()  # 查看对战信息,错误在那里
    print(ret)
    print('出错了')

 

使用try ... except的异常处理的好处
1、把错误处理和真正的工作分开
2、代码更易组织,更清晰,负责的工作任务更容易实现
3、更安全,不至于因为一些小的错误导致整个程序崩盘。
 
注:try...except 尽量少用,它本身就是附加给程序的一种异常处理的逻辑,与工作无关,过多会导致代码可读性变差,
 
3、Md5加密
import hashlib  # MD5需要导入这个模块
 # 加密的内容(需要的是字节类型)   
obj = hashlib.md5(b'')
obj.update('123456'.encode('utf-8')) # 把要加密的内容给md5
print(obj.hexdigest()) # 拿到密文
# 加密,不可逆
import hashlib
# 我自己的md5对象
def my_md5(s):
    obj = hashlib.md5(b"dhadkfkfnsgadsjndzjb") # 加盐
    obj.update(s.encode("utf-8")) # 把要加密的内容给md5
    return obj.hexdigest()

# print(my_md5("12345"))
# 9246295b87d00ec028dfec692efb55c0

username  = 'hutong'
password = '9246295b87d00ec028dfec692efb55c0'

# 登陆
uname = input('请输入你的用户名:')
upwd = input('请输入你的密码:')
if uname == username and my_md5(upwd) == password:
    print('登陆成功')
else:
    print('登陆失败')
应用
4、日志处理
 
    等级:
        critical:50  几乎是最高的
        error:40  平时使用最多
        warning:30  警告
        info:20    提示
        debug:10
 
import logging
# 配置好日志的处理, 默认就是GBK
logging.basicConfig(filename='x1.txt', # 把日志信息写入的文件名
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S', # 时间的格式
                    level=40) # 当前配置表示 10以上的分数会被写入日件


# 创建一个操作日志的对象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('腾讯qq', level=10) # 创建一个日志文件处理对象
logger1.addHandler(file_handler) # 把文件添加到日志

logger1.error("麻花藤明天请大家吃饭. 去不去?")

import traceback

class GenderException(Exception):
    pass


class Person:
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
        logger1.info(f"这个人的名字是{self.name}, 这个人的性别是:{self.gender}")

    def xizao(self):
        print(f"{self.name}在洗澡")

class ZaoTang:

    def nan(self, ren):
        if ren.gender == "":
            ren.xizao()
        else:
            raise GenderException("这里要的是男人")

    def nv(self, ren):
        if ren.gender == "":
            ren.xizao()
        else:
            raise GenderException("这里要的是男人")

try:
    p1 = Person("zhaoyalei", "")
    p2 = Person("linmei", "")
    zaotang = ZaoTang()
    zaotang.nan(p2)
    zaotang.nv(p1)
except GenderException:
    print("走错屋了")
    logger1.error("走错屋了.. ")
    logger1.error(traceback.format_exc()) # 把堆栈信息记录在日志文件中
例子

 

 
 
 
 
 
 
posted on 2018-12-21 21:02  古鲁月  阅读(135)  评论(0编辑  收藏  举报