1. 多重继承
- 首先在Python中是支持多重继承的。也就是我们可以为一个类同时制定多个父类。
- 可以在类名的()后面添加多个类,来实现多重继承。
- 多重继承会使子类同时拥有多个父类,并且会获取到所有父类中的方法。
- 在开发中没有特殊情况,应该劲量避免使用多重继承。因为多重继承会是我们的代码变得更加复杂。
- 如果多个父类中有同名发的方法,则会闲杂弟弟一个父类中找寻,然后找第二个,找第三个…前面会覆盖后面的。
- __base__ 可以获取当前类所有的父类,使用Class.__base__
- 如果多个父类中有同名的方法
# --------------------------------------Classroom Cases--------------------------------------
# 创建以个父类Sam
class Sam(object):
def speak1(self):
print('Hello, my name is Sam')
# 创建以个父类Janice
class Janice(object):
def speak2(self):
print('Hello, my name is Janice')
# 创建以个子类Mike
class Mike(Sam):
pass
print(Mike.__bases__)
# (<class '__main__.Sam'>,)
# 表示Mike子类是Sam,返回一个元组
# ‘,’表示可以有多个值
print(Sam.__bases__)
# (<class 'object'>,)
# 表示Sam父类是object。
'''多重父类,只要在子类的()中添加多个父类即可'''
# 在Mike子类中添加两个父类Sam和 Janice
class Mike(Sam, Janice):
pass
print(Mike.__bases__)
# (<class '__main__.Sam'>, <class '__main__.Janice'>)
# 表示Mike的父类有两个分别是Sam和Janice
mike = Mike()
mike.speak1() # Hello, my name is Sam
mike.speak2() # Hello, my name is Janice
'''当多个父类中有同样的方法,则会现在第一个父类中寻找,然后寻找下一个父类...前面的会将后面的父类所覆盖'''
class Sam(object):
def speak(self):
print('Hello, my name is Sam')
class Janice(object):
def speak(self):
print('Hello, my name is Janice')
class Mike(Sam, Janice):
pass
mike = Mike()
mike.speak()
# Hello, my name is Sam
# ---------------------------------------------------------------------
class Mike(Janice, Sam):
pass
mike = Mike()
mike.speak()
# Hello, my name is Janice
== 日常中不要使用多重继承 ==
2. 多态
- 多态是面向对象的三大特征之一。(有多种形态,一个对象可以不同的形态去呈现。)
# --------------------------------------Classroom Cases--------------------------------------
class Type1:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
class Type2:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
A = Type1('Sam')
B = Type2('Janice')
# 对于speak()这个歌函数,只要对象中有name属性,他就可以做为参数传递。
# 这个函数不会考虑对象的类型,只要有name属性就可以,name这个现象就是一个多态的体现。
def speak(obj):
print('Hello I am %s'%obj.name)
speak(A)
# Hello I am Sam
speak(B)
# Hello I am Janice
class Mike():
pass
c = Mike()
speak(C)
'''
print('Hello I am %s'%obj.name)
AttributeError: 'Mike' object has no attribute 'name'
'''
# 在speak2()中 做了一个类型检查,有obj为A的类型对象是,方可正常使用,其他的类型的对象将无法使用,这个函数就违反了多态。
'''定义一个函数'''
def speak2(obj):
if isinstance(obj,A):# 检查类型
print('Hello I am %s'%obj.name)
speak2(A) # Hello I am Sam
speak2(B) # 没有值,表明speak2 违反了多态,原因在speak2中有类型检查的判断。
A2 = speak2('John')
speak2(A2) # Hello I am John
len() 之所以一个对象可以通过他获得长度,是因为len()的多态性
面向对象的三大特性
封装:确保对象数据的安全性
继承:保证对象的扩展性
多态:保证程序的灵活性
3. 属性和方法
名称 |
---|
类属性 |
实例属性 |
实例方法 |
类方法 |
静态方法 |
class A(object):
# 类属性,直接在类中定义的属性就是类属性
# 类属性可以通过类或类的实例访问
# 类属性只能通过类对像去修改,无法通过是对象去修改
count = 0
def __init__(self): # __init__是实例方法
# 实例属性 通过实例对象添加的属性称之为实例属性 self.name = 'Sam'是实例属性
# 实例属性只能通过实例对象来访问和修改,类对象无法访问和修改
self.name = 'Sam'
# 实例方法是在我们类中直接定义的,以self为第一个参数开头的都是实例方法。
# 当通过实例对象去调用时,会自动将当前对象作为self传入。
# 当通过类对象去调用时,不会自动传递 A.test(a) = a.test()
def test(self): # test是实例方法
print('I am Sam')
# 类方法
# 类方法的第一个参数是cls, 他会自动传递,cls为当前传递对象 A.test2()=a.test2()
@classmethod
def test2(cls):
print('I am Janice')
# 静态方法
# 与当前类无关的一个方法,他只是保存当前类的一个函数
# 静态方法一般都是一些工具方法,与当前类无关
@staticmethod
def test3(cls):
print('I am Mike')
print(A.count)
a = A() # 创建A类的实例对象
# 实例属性 通过实例对象添加的属性称之为实例属性
a.count = 10 # 实例属性通过实例对象进行修改和访问
print('a',a.count) # 10
A.count = 123 # 类属性通过类对象进行修改和访问
print('A',a.count) # 123
print(a.name) # Sam
print(A.name)
'''
print(A.name)
AttributeError:type object 'A' has no attribute 'name'
'''# 对象 A 没有 name 属性,间接证明 name是实例属性,实例属性只能通过实例对象来访问。
a.test() # I am Sam
A.test()
'''
A.test()
TypeError:test() missing 1 required postional argument: 'self'
''' # 对象A访问实例对象,需要传递一个参数。
A.test(a) # I am Sam
A.test2() # I am Janice 类对象
a.test2() # I am Janice
A.test3() # I am Mike
a.test3() # I am Mike
4. 异常的简介
- 在程序运行的过程中会不可避免的出现一些错误,例如:没有赋值的变量,索引月结
- 错误称之为异常。一旦出现异常,会导致程序立即终止。
# --------------------------------------Classroom Cases----------------------------------
print('Hello')
print(a)
print('World')
'''
Hello
...
print(a)
NameError: name 'a' is not defined
'''
# 先运行print('Hello')语句,检测到print(a)语句错误,结束。不打印print('World')语句。
-
处理异常
-
程序运行的时候出现异常目的并不是让我们的程序直接终止
-
Python希望再出现异常的时候,我们编写相应的代码来进行处理
try 语句 try: 代码块(可能出现错误的语句) except: 代码块(出现错误之后处理的方式) else: 代码块(没有出现错误时要执行的代码)
# -------------------------------------Classroom Cases---------------------------------
print('Hello')
try:
print(a)
except:
print('Error......')
print('World')
'''
Hello
Error......
World
'''
print('Hello')
try:
print(10/1)
except:
print('Error......')
else:
print('10/1 = ',10)
print('World')
'''
Hello
10
10/1 = 10
World
'''
5. 异常传播
- 当在函数中出现了异常,如果在函数中跟对异常进行了处理,则遗产该不会在进行传播。如果函数中没有对异常进行处理,则异常会继续向函数调用传播。如果函数调用处处理了宜昌,则不再传播异常,如果没有处理则继续向调用处传播。直到传递到全局作用域(主模块)如果依旧没有处理,则程序终止,并显示异常信息。
def fn():
print('Hello World')
print(10/0)
fn()
'''
Hello World
Traceback (most recent call last):
File "C:\Users\Administrator\Desktop\yichang.py", line 4, in <module>
fn()
File "C:\Users\Administrator\Desktop\yichang.py", line 3, in fn
print(10/0)
ZeroDivisionError: division by zero
'''
# 当在函数中出现了异常,如果在函数中出现宜昌进行了处理,则异常不会再继续传播。
# 如果函数中没有处理异常,则异常继续向函数调用出传播。
# ----------------------------------处理方式-----------------------------------
def fn():
print('Hello World')
print(10/0)
try:
fn()
except:
pass
# Hello World
6. 异常对象
-
当程序运行过程中,出现一场以后,所有的异常信息会保存到一个专门的异常对象当中
-
而异常传播时,实际上就是异常对象抛给了调用处。
-
比如 ZeroDivisionError、NameError、IndexError…
try: print(a) print(10/0) except: print('Hello') # except后不跟任何内容,则此时它会捕获所有的异常。 # 当except后面跟内容时。 try: print(10/0) except NameError: print('NameError') except ZeroDivisionError: print('ZeroDivisionError') # ZeroDivisionError # 异常的继承就是exception # Exception 是所有异常的父类,所以Exception会捕获所有异常 try: print(10/0) except Exception: print('ZeroDivisionError') try: print(10/0) except Exception as e: print('ZeroDivisionError',e,type(e)) # ZeroDivisionError division by zero <class 'ZeroDivisionError'> # 最终 try: print(10/0) except Exception: print('ZeroDivisionError') finally: print('Finally')
try 语句
try:
代码块(可能出现错误的语句)
except 异常类型 as 异常名:
代码块(出现错误之后处理的方式)
except 异常类型 as 异常名:
代码块(出现错误之后处理的方式)
except 异常类型 as 异常名:
代码块(出现错误之后处理的方式)
except 异常类型 as 异常名:
代码块(出现错误之后处理的方式)
......
else:
代码块(没有出现错误时要执行的代码)
finally:
代码块(该代码块总会执行)
try语句用法要记住,只用一个try except else finally 搭配