类的约束 和 异常处理

本节主要内容:

  1.类的约束

  2.异常处理

  3.自定义异常

  4.MD5 加密

  5.日志

一 类的约束

  首先,你要清楚,约束是对类的越是,比如,你是一个项目经理,然后呢,你给手下的人分活,张三,你处理一下普通用户登录,李四,你处理一下会员登录,王五,你处理一下管理员登录,那这个时候呢,他们就开始分别去写他们的功能了,但是呢,你要知道,程序员不一定会有那么好的默契,很有可能三个程序员会写三个完全不同的方法,比如这样:

 1 class Normal:   # 张三,普通会员登录
 2     def login(self):
 3         pass
 4
 5 class Member:  # 李四,会员登录
 6     def denglu(self):
 7         pass
 8
 9 class Admin:   # 王五,管理员登录
10     def login(self):
11         pass

  然后呢,他们把代码交给你了,你看了一眼,张三和王五还算ok,这个李四写的什么鬼啊?denglu....

难受不??但是好歹能用,还能凑活,但是这时你这边要使用了,问题就来了

1 # 项目经理的入口
2
3 def login(obj):
4     print("准备验证码.....")
5     obj.login()
6     print("进入主页........")

  对于张三和王五的代码,没有问题,但是李四,你是不是调用不了,那如何避免这样的问题呢?我们要约束程序的结构,也就是说,在分配任务之前就应该把功能定义好,然后分别交给下面的程序员来完成相应的功能

  在python 中有两种办法来解决这样的问题

    1.提取父类,然后在父类中定义好方法,在这个方法中什么都不用干,就抛一个异常就可以了,这样所有的子类就必须重写这个方法,否则,访问的时候就会报错

    2.使用元类来描述父类,在元类中给出一个抽象方法,这样子类就不得不给出抽象方法的具体实现,也可以得到约束的效果

  首先,我们先看一种解决方案,首先,提取一个父类,在父类中给出一个方法,并且在方法中不给出任何代码,直接抛异常

 1 class Base:
 2     def login(self):
 3         raise Exception("你没有实现方法login()")
 4 class Normal(Base):
 5     def login(self):
 6         pass
 7
 8 class Member(Base):
 9     def denglu(self):
10         pass
11
12 class Admin(Base):
13     def login(self):
14         pass
15
16 # 项目经理的入口
17 def login(obj):
18     print("准备验证码.....")
19     obj.login()
20     print("进入主页........")
21
22 n = Normal()
23 m = Member()
24 a = Admin()
25 login(n)
26 login(m)   # 报错 Exception: 你没有实现方法login()
27 login(a)

  在执行 login(m)的时候程序会报错,原因是,此时访问的 login() 是父类总的方法,但是富尅 的方法会抛出一个异常,所以报错,这样程序员就不得不写 login方法了,从而对子类进行了相应的约束

  在本例中,要注意,我们抛出的是 Exception 异常,而 Exception 是所有异常的根,我们无法通过这个异常来判断出程序 是因为什么报的错,所以,最好是换一个 专业的错误信息,最好是换成 NotlmplementError

其含义是"没有实现的错误" 这样程序员 或者 项目经理 可以一目了然的知道是什么错了,就好比,你犯什么错了,你也不知道哪里错了,这时我告诉你,你xx 错了,你改也知道改哪不是?

  第二套方案,写抽象类 和抽象方法,这种方案相对于上一种方案来说麻烦一些,需要先引入一个抽象的概念,什么是抽象呢?这里动物的吃就是一个抽象的概念,只是一个动作的概念,没有具体实现,这就是抽象的动作,换句话说,我们如果写一个方法,不知道方法的内部应该到底怎么写,那这个方法其实就应该是一个抽象的方法,如果一个类中包含抽象方法,那么这个类一定是一个抽象类,抽象类是不能有实例的,比如,你看看一些抽象派的画作,在现实中是不存在的,也就无法建立实例对象与之相对应,所以抽象类无法创建对象,创建对象的时候会报错.

  在 python 中编写一个抽象类比较麻烦,需要 引入 abc 模块中的 ABCMeta 和 abstractmethod 这两个内容,来看一个例子

 1 from abc import ABCMeta,abstractmethod
 2
 3 # 类中包含了抽象方法,那此时这个类就是个抽象类,注意:抽象类可以有普通方法
 4 class IGame(metaclass=ABCMeta):
 5     # 一个游戏到底怎么玩儿?你能形容?路程能一样么?
 6     @abstractmethod
 7     def play(self):
 8         pass
 9
10     def turn_off(self):
11         print("破游戏不玩了,脱坑了")
12
13 class DNFGame(IGame):
14     # 子类必须实现父类中的抽象方法,否则子类也是 抽象类
15
16     def play(self):
17         print("dnf 的玩儿法")
18
19 # g = IGame()      #  抽象类不能创建对象
20
21 dg = DNFGame()
22 dg.play()

  通过代码我们发现这里的 IGame 对 DNFGame 进行了约束,换句话说,父类对子类进行了约束

from abc import ABCMeta,abstractmethod

class Base(metaclass=ABCMeta):
    @abstractmethod
    def login(self):
        pass

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

class Member(Base):
    def denglu(self):     # 这个没用了
        pass
    def login(self):     # 子类对 父类 进行 实现
        pass
class Admin(Base):
    def login(self):
        pass

# 项目经理入口

def func(obj):
    print("准备验证码...")
    obj.login()
    print("进入主页.....")

n = Normal()
m = Member()
a = Admin()
func(n)
func(m)
func(a)

  总结:约束,其实就是父类对子类进行的约束,子类必须要按照父类的要求 写 xx方法,在python中 约束的方式有两种:

  1.使用抽象类和抽象方法,由于该方案来源是 java 和 c# ,所以使用频率还是很少的

  2.使用人为抛出异常的方案,并且尽量抛出的是 NotlmplementError,这样比较专业,而且错误比较明显

二 异常处理

  首先我们说一下,什么是异常, 异常 是程序在运行过程中产生的错误,就好比,你在回家的路上突然天塌了,那这个属于一个异常,总之就是不正常,那如果程序出现了异常,怎么处理呢?

  我们先制造一个错误,来看看异常长什么样

def chu(a,b):
    return a/b

ret = chu(10,0)
print(ret)
# 结果:
# ZeroDivisionError: division by zero

  什么错误呢?除法中除数不能为0,那如果真的出了这个错,你把这一对错误抛给使用者嘛? 肯定不能啊

那如何处理呢???

def chu(a,b):
    return a/b
try:
    ret = chu(10,0)
    print(ret)
except Exception as e:
    print(e)
    print("除数不能为0")
# 结果:
# division by zero
# 除数不能为0

  那么 try ....except 是什么意思呢?尝试着运行 xxxx代码,出现了错误,就执行 except 后面的代码,在这个过程中,当代码出现错误的时候,系统会产生一个异常对象,然后这个异常 会向外抛,被 except 拦截, 并把接收到的异常对象 赋值给 e,那这里的 e 就是异常对象, 那这里的  Exception 是什么呢?  Exception 是所有的异常的 基类(父类) ,也就是异常的根,换句话说,所有的错误都是 Exception 的子类,那这样写 好像有点问题啊, Exception 表示所有的错误,太笼统了,所有的错误都会被认为是 Exception,当程序出 多种错误的时候,就不好分类了,组好事什么异常就用什么处理,这样就更加合理了,所以在  try...except 语句汇总,还可以写入更多的 except

try:
    print("各种操作...")
except ZeroDivisionError as e:
    print("除数不能为0")
except FileNotFoundError as e:
    print("文件不存在...")
except Exception as e:
    print("其他错误")

  此时,程序运行过程中,如果出现了ZeroDivisionError 就会被第一个 except 捕获,如果出现了FileNotFountError 就会被第二个 except 捕获,如果都不是这链各个异常,那就会被最后的 Exception  捕获,总之最后的 Exception 就是我们处理 异常的最后一道防卫,这是我们 最常用的一套写法, 接下来看一套最完整的 异常处理写法(语法):

try:
    """ 操作"""
except Exception as e:
    """ 异常的父类,可以捕获所有的异常..."""
else:
    """保护不抛出异常的代码,当try 中 无异常的时候执行..."""
finally:
    """最后总是要执行我...."""

  解读:程序先执行操作,然后如果出错了会走 except的代码,如果不出错,这行else 中的代码,不论出不出错,最后都要执行 finally 中的 语句, 一般我们 用 try...except 就够了,顶多加上 finally ,finally 一般用来作为收尾工作

  上面是处理异常,我们在执行代码的过程中如果出现了一些条件上的不对等,根本不符合我的代码逻辑,比如,参数,我要求你传递一个数字,你非传递一个字符串,那 "对不起,我是 警察" 哈哈哈....... 这样的我是没办法处理的,那如何通知你呢? 两个 方案:

  1.方案1: 直接返回即可,我不管你

  2.方案2: 抛出一个异常,告诉你,我不好惹,乖乖的听话

  第一种方案是我们之前写代码经常用到的方案,但这种方案并不够好,无法起到警示作用,所以,以后的代码中出现了类似的问题,直接抛出一个错误,那怎么抛呢? 我们要用到  raise 关键字

def add(a,b):
    """
    给我传递两个参数,我帮你计算这两个数的和
    :param a:
    :param b:
    :return:
    """
    if not type(a) == int and type(b) == int:
        """ 当程序运行到这句话的时候,整个函数的调用会中断,抛出一个异常"""
        raise Exception("不是整数,臣妾做不到啊")
    return a + b
# 如果调用方不处理异常,那产生的错误将会继续往外抛,最后就抛给了使用者
# add("你好,我叫  张曼玉")
#  如果 调用方吹了异常,那么错误就不会 抛给使用者,程序也能正常运行
try:
    add("我是至尊宝","你是紫霞仙子嘛?")
except Exception as e:
    print("报错了,你自己看着办吧")

  当程序运行到 raise 的时候, 程序会被中断,并实例化后面的异常对象,抛给调用方,如果调用方不处理,则会把错误继续向上抛出,最后抛给 使用者,如果调用方处理了异常,那程序可以正常运行了

  说了这么多,异常也知道如何抛出 和 处理了,但是现在我们用的都是 python 自带 的异常,如果有一天,你自己写的代码中 出现了 一个 无法用现有的 异常来解决,那怎么办? 试试,能不能 ,自定义一个??/

  其实 自定义一个 也很简单,只要你的类继承 了 Exception 类,那你的类就是一个 异常类,就这么简单.

# 继承 Exception ,那这个类就是一个 异常类

class GenderError(Exception):
    pass

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

def men_bathroom(person):
    if person.gender != "男":
        raise GenderError("性别不对,这里是男澡堂")

p1 = Person("哈哈哥","男")
p2 = Person("嘻嘻姐","我不知道")

# men_bathroom(p1)
# men_bathroom(p2)  # 会抛出一个异常  GenderError

# 处理异常
try:
    men_bathroom(p1)
    men_bathroom(p2)
except GenderError as e:
    print(e)    #  性别不对,这里是男澡堂
except Exception as e:
    print("反正报错了")

    搞定了,但是,如果是真的报错了,我们在测试的时候,最好是能看到错误源于哪里,怎么办呢? 需要引入一个模块, traceback,这个模块可以获取到我们每个方法的调用信息,有被称为堆栈信息,这个信息对我们排错很有帮助的

import traceback
# 继承 Exception,那这个类 就是一个 异常类

class GenderError(Exception):
    pass

class Person:

    def __init__(self,name,gender):
        self.name = name
        self.gender = gender
def men_bathroom(person):
    if person.gender != "男":
        raise GenderError("性别不对,别进了")

p1 = Person("哈哈哥","男")
p2 = Person("嘻嘻姐","不知道哎")

try:
    men_bathroom(p1)
    men_bathroom(p2)
except GenderError as e:
    val = traceback.format_exc()     # 获取到堆栈信息
    print(e)                         # 性别不对,别进了
    print(val)
except Exception as e:
    print("反正错了")
# 结果
# 性别不对,别进了
#     raise GenderError("性别不对,别进了")
# GenderError: 性别不对,别进了

  搞定了,这样我们就能收放自如了,当测试代码的时候吧 堆栈信息打印出来,但是当到了线上的生产环境的时候把这个堆栈去掉即可

四 MD5加密

  想一个事情. 你在银行取钱或者办卡的时候. 我们都要输入密码. 那这个密码如果就按照我们输入的那样去存储. 是不是很不安全啊. 如果某一个程序员进入到了了银行的数据库. 而银行的数据库又存的都是明文(不加密的密码)密码. 这时, 整个银行的账户里的信息都是非常不安全的. 那怎么办才安全呢? 给密码加密. 并且是不可逆的加密算法. 这样. 即使获取到了银行的账户和密码信息. 对于黑客而言都无法进行破解. 那我们的账号就相对安全了了很多. 那怎么加密呢? 最常见的就是用MD5算法.

  MD5是一种不可逆的加密算法. 它是可靠的. 并且安全的. 在python中我们不需要手写
这一套算法. 只需要引入?个叫  hashlib 的模块就能搞定MD5的加密工作

import hashlib

obj = hashlib.md5()
obj.update("哈哈哥".encode("utf-8"))  # 加密的必须是字节
miwen = obj.hexdigest()
print(miwen)

# 如果担心被破解,也就是 撞库,可以加盐,对没错,就是  加盐

import hashlib

obj = hashlib.md5(b"saddfgflhmdlfmdas")      # 加盐
obj.update("alex".encode("utf-8"))
miwen = obj.hexdigest()
print(miwen)
# 现在可以了,不会再担心 撞库了

  那 MD5 怎么用呢??

import hashlib

def my_md5(s):
    obj = hashlib.md5()
    obj.update(s.encode("utf-8"))
    miwen = obj.hexdigest()
    return miwen
username = input("输入用户名:")
password = input("输入密码:")
# 数据存储 的时候:
# username:my_md5(password)
# 假设现在的用户名 和 密码分别是
# hahage:b3ed7cbc208610c252e2ea825c5f31e5
# 123456:e10adc3949ba59abbe56e057f20f883e
# print(my_md5(username))
# print(my_md5(password))

# 用户登录
if my_md5(username) == "b3ed7cbc208610c252e2ea825c5f31e5" and     my_md5(password) == "e10adc3949ba59abbe56e057f20f883e":
    print("成功")
else:
    print("失败")

  所以,以后存密码就不要存明文了,要存密文,安全,并且,这里的加盐不能改来改去的 ,否则,整套密码就都乱了

原文地址:https://www.cnblogs.com/wenqi2121/p/10325050.html

时间: 2024-08-30 11:30:06

类的约束 和 异常处理的相关文章

约束和异常处理

本节主要内容: 1. 类的约束 2. 异常处理理 3. 自定义异常 4. MD5加密 5. 日志 一.类的约束 首先,要清楚.约束是对类的约束.每个人和每个人写代码用的方法名和类名都不一样假如你处理一个用户登录,有三个不同级别的登陆要求分别分给三个人写你要知道程序员不一定有那么好的默契.很有可能三个人会写不同的方法,比如就像是这样: class Normal: # 张三, 普通?登录 def login(self): pass class Member: # 李四, 会员登录 def dengl

python之路--类的约束, 异常处理, MD5, 日志处理

1. 类的约束 1. 写一个父类,父类中的某个方法要抛出一个异常 NotImplementedError class Base: # 对子类进行了约束. 必须重写该方法 # 以后上班了. 拿到公司代码之后. 发现了notImplementedError 继承他 直接重写他 def login(self): # 没有被实现错误 raise NotImplementedError("你要重写一下login这个方法. 否则报错!") # 抛异常 . class Member(Base): d

Python基础20_类的约束,异常处理,MD5加密,日志

一. 类的约束 约束程序的结构, 在分配任务之前就应该把功能定义好, 然后分别交给底下的程序员来完成相应的功能 在python中有两种办法来解决这样的问题 1. 提取父类, 然后在父类中定义好方法, 在方法中抛出一个异常, 这样所有继承父类的子类都必须重写这个方法, 否则访问的时候就会报错 class Base: def login(self): raise NotImplementedError   # 没有被实现错误, 要求子类必须重写login方法 , 不然抛出异常 class User(

pyrhon类约束及异常处理和日志模块

类的约束 class Base: #对子类进行了约束,必须重写该方法 def login(self): print('方法错误,必须用定义login方法') # 发现了notImplementedError继承他,直接重写他 # raise NotImplementedError("你要重写一下login这个方法,否则报错!") # 抛异常 class Member(Base): def login(self): print('我的功能是普通用户登录') class Admin(Bas

Python 18 约束和异常处理

约束和异常 1.类的约束 提取父类. 然后在子类中定义好方法. 在这个方法中什么都不用干. 就抛一个异 常就可以了. 这样所有的子类都必须重写这个方法. 否则. 访问的时候就会报错 使用元类来描述父类. 在元类中给出一个抽象?法. 这样子类就不得不给出抽象 方法的具体实现. 也可以起到约束的效果. 方法一 ↓↓↓ def login(self): raise Exception("你没有实现login?法()") class Normal(Base): def login(self):

was8.5和aop的问题:JVMVRFY013 违反类装入约束

一.错误日志:Error 500: javax.servlet.ServletException: java.lang.VerifyError: JVMVRFY013 违反类装入约束 类=org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint,方法=getSourceLocation()Lorg/aspectj/lang/reflect/SourceLocation;,pc=0 二.问题描述: 这是由于was8.5和

多继承,封装,多态,super()方法,类的约束

多继承: 多继承就是一个类里有多个父类,父类也可以有多个爷爷类.从多个父类中继承属性跟方法. 类的分类: python2.2之前,只有经典类,pythont2.2之后出现了新式类 经典类:不继承object类,多继承遵循深度优先,从左至右,一条路走到底 class A:pass 新式类:继承object类,多继承遵循c3算法,mro方法. class A(object):pass python3x版本只有新式类. 鸭子类型:两个结构类似,有弱关联关系的函数或者类. mro方法:(面试会考) 计算

封装,多态,继承. super的方法,类的约束,

1.python的三大特性:python的三大特性,封装,多态,继承封装:函数 模块 类 对象多态 : python中默认支持多态继承: python中的子类继承父类属性和方法 鸭子类型: 看着像鸭子,它就是鸭子python中处处都是鸭子 # 两者之间没有任何关系,但是都遵循着一个隐形的标准两个类中的鸭子类型:# 优点:1,统一标准,减少了词汇量# 2,两者之间没有任何耦合性,但是可以产生关系,其中一个的对象可以调用另一个类的方法# 其他例子 :index pop clear 2. super的

封装 多态 类的约束 super

python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到?个对象中. 把固定功能的代码封装到?个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了?个很?B的函数. 那这个也可以被称为封装. 在?向对象思想中. 是把?些看似?关紧要的内容组合到?起统?进?存储和使?. 这就是封装. 2. 继承: ?类可以?动拥有?类中除了私有属性外的其他所有内容. 说?了, ??可以随便?爹的东?. 但是朋友们, ?定要认清楚?个事情.