继承
多重继承
- Python中支持多重继承(开发中很少使用多重继承,且尽量避免多重继承)
- 多个父类中有同名的方法,则在第一个父类寻找,然后再找第二个,以此类推
- 类名.__bases__ —— 获取当前类的所有父类
- 类名.__mro__ —— 获取继承执行的顺序
class A:
def text(self):
print('我是A')
class B:
def text(self):
print('我是B')
class C(A,B): #根据继承顺序寻找,A在前,先找A的方法,如果B在前,现在B的方法
pass
c = C()
c.text() # 我是A
C.__bases__ # (<class '__main__.A'>, <class '__main__.B'>)
C.__mro__ # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
多态
- 多态是面向对象德三大特性之一
- 概念 —— 对象可以通过不同的形态去呈现(多种形态)
- 表现形式 —— 一个可以传递对象的函数中,代码块中有调用这个对象的属性或方法,它就可以作为参数传递。这个函数不会考虑对象的类型,只要有对象的属性或方法就可以,那么这个现象就是一个多态的体现。如果这个函数中做了一个类型的检查,只有特定类才可以使用时,这个函数就违反了多态特性
# 多态的体现
class A:
name = 'A'
class B:
name = 'B'
def text(obj):
print ('我是%s' % obj.name)
a = A()
b = B()
text(a) # 我是A
text(b) # 我是B
# 违反多态特性
class A:
name = 'A'
class B:
name = 'B'
def text(obj):
if isinstance(obj,A):
print ('我是%s' % obj.name)
a = A()
b = B()
text(a) # 我是A
text(b) # 无打印结果
面向对象特性的总结
- 封装 —— 保证对象中数据的安全
- 继承 —— 保证对象的扩展性
- 多态 —— 保证对象的灵活性
类属性、方法和实例属性、方法总结
- 类属性 —— 直接在类中定义的属性称为类属性
- 类属性可以通过类对象和实例对象访问
- 类属性只能通过类对象修改
class A:
num = 0
a = A()
A.num # 0
a.num # 0
a.num = 1
a.num # 1
A.num # 0
A.num = 5
a.num # 1(a.num = 1已经给实例对象创建和类对象的同名属性并赋值,因此必须删除实例对象属性后才能获取类对象属性)
del a.num
a.num # 5
A.num # 5
-
实例属性 —— 通过实例对象添加的属性称为实例属性
- 实例属性只能通过实例对象访问和修改
- 类对象无法访问和修改实例属性
-
实例方法 —— 直接在类中定义的方法称为实例方法
- 以self参数开头的都是实例方法
- 通过实例对象调用时,会自动将实例对象作为self参数传入
- 通过类对象调用时,不会自动作为self参数传入
# 实例属性和方法
class B:
def __init__(self):
self.name = '哈哈'
def run(self):
print('我在跑步')
b = B()
b.name # '哈哈'
B.name # AttributeError: type object 'B' has no attribute 'name'
b.run() # 我在跑步
B.run() # TypeError: run() missing 1 required positional argument: 'self'
- 类方法 —— 需要在方法上一行添加装饰器(@classmethod)
- 以cls参数开头的,且有@classmethod装饰器的方法称为类方法
- 类方法可以通过类对象和实例对象访问
class C:
#classmethod
def test(cls):
print('测试类方法...')
c = C()
C.test() # 测试类方法...
c.test() # 测试类方法...
- 静态方法 —— 需要在方法上一行添加装饰器(@staticmethod)
- 参数为空,且有@staticmethod装饰器的方法称为静态方法
- 静态方法基本上是一个和当前类无关的方法,它只是保存在当前类的一个函数
- 通常是一些工具方法,和当前类无关
class D:
@staticmethod
def opendoor():
print('正在开门...')
d = D()
D.opendoor() # 正在开门...
d.opendoor() # 正在开门...
异常
异常的简介
- 在程序运行过程中不可避免出现一些错误,这些错误称为异常
- 在程序运行过程中出现异常,会立即终止程序的执行(无法继续执行)
异常的处理
- 异常处理的目的
- 程序运行时出现异常的目的不是让程序直接终止
- 在出现异常的时候,编写响应的代码来进行处理
- 语句:
try:
代码块(可能出现错误的语句)
except 异常类型(Exception可以捕获所有异常) as 异常名:
代码块(错误之后的处理方式)
else:
代码块(没有出错要执行的语句)
finally:
代码块(是否出现异常都会执行的语句)
# 出现错误的情况
print('程序开始')
try:
print(a)
except:
print('程序出错')
else:
print('程序有问题')
finally:
print('程序结束')
结果:
程序开始
程序出错
程序结束
# 没有出错误的情况
print('程序开始')
try:
print(10/2)
except:
print('程序出错')
else:
print('程序没问题')
finally:
print('程序结束')
结果:
程序开始
5.0
程序没问题
程序结束
异常的传播
- 在函数或类中对异常进行处理,则异常不会传播
- 可以在函数内部或类内部进行异常处理
- 可以在函数调用处或类对象、实例对象调用处进行异常处理
- 在函数中没有对异常进行处理,则异常会向函数调用处传播(可以多次传播),直到传递到全局作用域,如果依然没有处理,则程序终止,并显示异常信息
异常处理
# 函数内部异常处理示例
def fn():
try:
print('我是fn')
print(name)
except:
print('程序有错误')
fn()
结果:
我是fn
程序有错误
# 函数调用处异常处理示例
def fn():
print('我是fn')
print(name)
try:
fn()
except:
print('程序有错误')
结果:
我是fn
程序有错误
# 异常传播示例
def fn():
print('我是fn')
print('异常传播测试...')
print(name)
def fn1():
print('我是fn1')
fn()
def fn2():
print('我是fn2')
fn1()
fn2()
结果:
我是fn2
我是fn1
我是fn
异常传播测试...
Traceback (most recent call last):
File "python文件名", line 46, in <module>
fn2()
File "python文件名", line 45, in fn2
fn1()
File "python文件名", line 41, in fn1
fn()
File "python文件名", line 37, in fn
print(name)
NameError: name 'name' is not defined
异常对象
- 当程序出现异常后,所有的异常信息会保存到一个专门的对象中,而异常传播时,实际上是异常对象抛给调用处
- 所有异常对象的父类是Exception(查看python文档:Library Reference中Built-in Exceptions)。如果except后面是Exception,可以捕获所有异常。
def fn():
print('我是fn')
print(name)
print(10/0)
try:
fn()
except NameError:
print('程序有没有定义的变量')
结果:
我是fn
程序有没有定义的变量
def fn():
print('我是fn')
print(10/0)
print(name)
try:
fn()
except NameError:
print('程序有没有定义的变量')
结果:
Traceback (most recent call last):
File "XXX.py", line 84, in <module>
fn()
File "XXX.py", line 81, in fn
print(10 / 0)
ZeroDivisionError: division by zero
我是fn
def fn():
print('我是fn')
print(10 / 0)
print(name)
try:
fn()
except Exception as e:
print('程序出现错误%s' %e, type(e))
结果:
我是fn
程序出现错误division by zero <class 'ZeroDivisionError'>