异常类型
复习
继承
1.父类:在类后()中写父类
class A:pass
class B:pass
class c(A,b):pass
2.属性查找:自己 ——> ()左侧的父类 --> 依次往右推
3.抽离:先定义子类,由子类的共性抽离出父类
派生:父类已经创建,通过父类再去派生子类
4.继承关系
1.父类的所有非封装的属性和方法均能被继承
2.父类的所有封装的属性和方法均不能被继承
3.在子类中要去使用父类的方法
1.子类继承父类方法:子类不需要去实现父类的方法,子类对象可以直接调用父类
2.重写父类的方法:方法名与父类相同,实现体不同,子类对象调用的是自身方法
3.重用父类的方法:方法名与父类相同,实现体中有自己的逻辑也调用了父类的方法(supper())
-- super():在子类中获取可以调用父类方法的对象,且在父类中体现的调用子类或子类对象。(调用父类,并在子类对象中产生使用)
5.复杂继承:一个类可以继承多个类,查找顺序是根据继承父类从左往右的顺序,并在查找第一个父类时,将父类的父类也进行查找(一个父类分支全部查找完毕才去查找下一个父类分支)
6.菱形继承
1.经典类:py2中类不默认继承object,所以没有明确继承的类就没有继承任何类,这样的类就称之为经典类
2.新式类:所有直接或间接继承了object的类,py2中主动继承object的类以及py3中所有的类
前提:父类中共有属性或方法,子类没有自己去定义这些属性和方法,必须从父类中获取,到底从哪个父类中获取
--经典类:深度查找
--新式类:广度优先
今日内容
#接口思想
#抽象类思想 *
#多台: 1.继承关系的多态 2.鸭子类型的多态 *****
#内置(魔法)方法:格式化方法 __len__ ,析构方法
#反射 ****
#异常处理 ***** 使用简单,在哪里使用思想复杂
接口
#建立关联的桥梁的作用,方便管理代码(就说明可以不存在)
#为类拓展功能的作用(ex.继承一个专门提供方法的类,子类就拓展了功能,接口的思想)该类的方法一般不需要实现体,由继承方法的子类去实现
#某些子类才具有的方法可以全写在父类中,但是语法正确但是逻辑上有误,不推荐
1.python中没有接口语法
print(len('123'))#清晰知道操作的功能,但不明确操作的具体对象(面向过程)
print('123'.__len__)#清晰知道操作的对象,但不明确具体的操作方法(面向对象)
# 提供所有宠物应该有的功能
class PetInterface:
def close_master(self): pass
# 提供所有看门应该有的功能
class WatchInterface:
def watch_door(self): pass
# 没有去继承PetInterface,WatchInterface的Dog就是普通的Dog类
# 但继承了PetInterface,该Dog就可以作为宠物狗,同理继承WatchInterface就可以作为看门狗
class Dog(PetInterface, WatchInterface):
def jiao(self): pass
def chi(self): pass
def pao(self): pass
# 一定要重写接口的方法
pass
# 可以作为宠物及看门猫
class Cat(PetInterface, WatchInterface): pass
抽象类
抽象父类:拥有抽象方法(子类共有的方法,但是父类不能有具体的实现体)的父类
抽象方法:方法名是具体的,但是实现体是抽象的(在子类中重写具象化)
注意点:有抽象方法的父类不能被实例化(假设能被实例化,就可以调用自己的抽象方法没有任何意义)
#实现抽象父类的语法
import abs
class Sup(metaclass=abc.ABCMeta)
#抽象父类的抽象方法,子类必须重写
#抽象父类中的功能下的实现体有无没有区别,就算被引用也不实现。
多态
多态:对象的多种状态- 父类对象的多种(子类对象)状态
import abc
class People(metaclass=abc.ABCMeta):
def __init__(self, name):
self.name = name
鸭子类型
#需求:需要一个对象,该对象有name属性及speak方法,就可以称为一种状态的体现被传入
def ask_someone(obj):
print('让%s上台演讲'%obj.name)
obj.speak()
#鸭子类型
1.先规定:有什么属性和什么方法的类型叫做鸭子类型
2.这些类实例化出的对象,都称之为鸭子,都可以作为需求对象的一种具体体现
class A:
#能有自己独有的属性和方法,可以完全和B不一样,但是必须有鸭子类型规定的属性和方法,不然就不是鸭子类型
def __init__(self,name):
self.name = name
def speak(self):
print('say AAAA')
class B:
#能有自己独有的属性和方法,可以完全和A不一样,但是必须有鸭子类型规定的属性和方法,不然就不是鸭子类型
def __init__(self,name):
self.name = name
def speak(self):
print('say BBBB')
ask_someone(B('B'))
格式化方法与析构方法
class A:
def __init__(self,name,age)
self.name = name
self.age = age
#格式化方法:在外界答应该对象就是调用
#格式化外界直接打印该类对象的字符串表示结果
def __str__(self)
# return 'abc' #外界打印A类的对象,都打印 字符串abc
# return 'super().__str__() #系统默认的在父类中返回的是对象存放的地址信息
return '<name:%s | age:%s>' % (self.name, self.age) # 根据对象实际的属性格式化具体的输出内容
#析构方法:在对象被消耗的那一刹那被调用,在被消耗前做一些事情
def __del__(self):
#del会在self代表的对象被消耗的时候调用
#我们可以在析构函数中释放该对象持有的其他资源
#或者将一些持有资源持久化(保存到文件或数据库中)
def self.name
a=A('老王',88)
print(a,type(a))
import time
# return super().__str__() # 系统默认的在父类中返回的是对象存放的地址信息
了解
class B
#了解:对象.语法的内部实现
def __setattr__(self,key,value)
self.__dict__[key] = value #系统默认实现,在名称空间添加名字
# self.__dict__[key] = value.lower() # 可以自定义处理一些内容
#了解:将对象添加属性的方式同字典
def __setitem__(self,key,value)
self.__dict__[key] = value
b = B()
# 设置
b.name = 'BBB' # 内部走的是 __setattr__
b['age'] = 18 # 内部走的是 __setitem__
# 访问
print(b.name)
print(b.age)
反射
#反射:通过字符串与类及对象的属性(方法)建立关联
class A:
num = 10
print(hasattr(A,'num'))
res=print(getattr(A,'num','默认值'))
print(res)
delattr(A,'num')
print(setattr(A,'tag',10))
#类的属性来操作
class B:
def __init__(self, name):
self.name = name
print(hasattr(b, 'name'))
print(getattr(b, 'name', '对象的属性类不能获取'))
delattr(b, 'name')
print(setattr(b, 'age', 18))
# 对象的属性对象来操作
class C:
def fn(self):
print('fn')
异常
#程序中的异常处理机制
1.程序中的所有异常都会被处理
2.程序中的所有异常都需要手动处理
3.如果没有手动处理异常,异常就会交给python处理器处理
- - 处理的方式就是打印异常信息,并停止接收器
#异常信息的三部分
1.异常的追踪信息:提示错误位置
2.异常的类型:告知处理异常应该捕获什么类型
3.异常的内容:告知错误信息
#处理异常的语法
try:
#会出现异常的代码块
except(异常类型1,异常类型2) as 异常别名:
# 异常处理逻辑
else:
# 没有出现异常会执行该分支
finally
无论是否出现都会执行该分支
异常语法
#将可能出现异常的代码放在try分支进行检测
# - -如果不出现异常,正常执行内部所有代码
# - - 如果出现异常会进入except分支
#part1
#1.建议大家对异常处理时,一次只处理一个异常
try:
print(asdsdsdsdsdsdsdsdsdsdsdsdsd) # NameError
except NameError: # except 后跟异常类型,如果不需要查看异常信息,可以省略异常信息
print('出现了NameError异常')
try:
ls = [1, 2, 3, 4, 5]
print(ls[10]) # IndexError
except IndexError as e: # 如果想知道异常信息,用别名接收
print('出现了IndexError异常: %s' % e)
# part2
# 2.如果无法避免一句话或是一个完整的代码结构会出现多个可能的异常,需要在一个try中提供多个except
# ls = [1, 2, 3, 4, 5]
ls = (1, 2, 3, 4, 5, 6)
# try:
# print(ls[5]) # IndexError
# ls.append(10) # AttributeError
# except IndexError as e:
# print('出现了IndexError异常: %s' % e)
# except AttributeError as e:
# print('出现了AttributeError异常: %s' % e)
try:
print(ls[5]) # IndexError
ls.append(10) # AttributeError
except (AttributeError, IndexError) as e:
print('出现了异常: %s' % e)
print('===============================')
# part3
# 3.有些异常提前无法明确,或是压根没有明确的必要,可以捕获异常的父类异常
ls = [1, 2, 3, 4, 5]
# ls = (1, 2, 3, 4, 5, 6)
try:
print(ls[5]) # IndexError
ls.append(10) # AttributeError
except Exception as e: # 可以通过多态的应用,捕获父类,只要抛出的是该父类的子类异常,均可以被捕获
print('出现了异常: %s' % e)
# BaseException:所有异常的基类 | Exception:常规错误的基类
# part4
# 4.了了解 - try语法的else分支:当try检测的代码块没有出现异常,才会走else分支
try:
print(aaaa)
except Exception as e:
print('出现了异常', e)
else:
print('没有异常')
# part5
# 5.finally:无论是否出现异常都会执行该分支
try:
f = open('1.txt', 'w', encoding='utf-8')
f.write(b'123')
except Exception as e:
print('出现了异常', e)
finally:
print('无论是否出现异常都会执行该分支')
f.close() # 文件只要打开,不管操作是否出现异常,都需要释放文件资源
自定义异常
#自定义异常的目的:想抛一个有意义的异常,但这个异常系统没有提供,自定义一个
class PeopleNameError(Exception): #exception |BaseException
# pass
# 可以通过__init__明确外界的错误信息接收给那个属性
# 再在__str__中格式化外界捕获异常,打印异常信息的格式
def __init__(self, msg):
self.msg = msg
def __str__(self):
return 'PeopleNameError: ' + self.msg
def get_name():
name = input('name: ')
if 'sb' in name.lower():
raise PeopleNameError('人名不能有敏感词汇')
return name
try:
print(get_name())
except PeopleNameError as e:
print(e) # PeopleNameError: 人名不能有敏感词汇
断言
num = int(input('num'))
assert num <0 #断言:只有满足断言条件,程序才能往下执行,反之抛出异常
print(abs(num))
异常表
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
SystemExit | Python 解释器请求退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |