错误异常处理与面向对象
类是一类事物的统称,比如学生。对象就是类的实例化。
类有属性(变量),比如学生的姓名、性别、年龄、成绩等,也就是编程里面的变量。
类有方法(函数),比如学生的上课、下课等,也就是编程里面的函数。
类是一种数据结构,我们可以用它来定义对象,对象把数据值和行为特性融合在一起。Python 使用class
关键字来创建类:通常类名的第一个字母大写,推荐使用驼峰式命名法,单词首字母均大写。类由属性(变量)和方法(动作,函数)组成。
class ClassName(bases):
'class documentation string' #'类文档字符串'
class_suite # 类体
__init__()
是类的实例(对象)创建后第一个被调用的方法,通常被用来进行对象中属性(变量)的初始化。设置实例的属性可以在实例创建后任意时间进行,但是通常情况下优先在__init__()
方法中实现。
# 04 - __init__.py
class Stu():
def __init__(self,name,sex,age,score):
self.name=name
self.sex=sex
self.age=age
self.score=score
stu1=Stu(name="ghui",sex=True,age=18,score=59.9)
print(f"{stu1.name}的成绩为:{stu1.score}")
方法仅仅是类内部定义的函数,方法只有在其所属的类拥有实例时,才能被调用;任何一个方法定义中的第一个参数都是变量self,它表示调用此方法的实例对象就是自己。
类中的方法,也就是类中定义的函数,这个函数第一个参数永远是self,表示自己。
# 05 - 绑定方法.py
import time
class Stu():
def __init__(self,name,sex,age,score):
self.name=name
self.sex=sex
self.age=age
self.score=score
def getScore(self):
print(f"{self.name}的成绩为: {self.score}")
def goodGoodStudy(self):
print("好好学习中...")
time.sleep(10)
self.score +=0.1
stu1=Stu(name="ghui",sex=True,age=18,score=59.9)
stu1.getScore() # ghui的成绩为: 59.9
stu1.goodGoodStudy() # 好好学习中...
stu1.getScore() # ghui的成绩为: 60.0
输出结果:
继承描述了基类(祖先)的属性如何遗传给派生类(子孙),子类可以继承它的基类的任何属性,不管是数据属性还是方法。
# 06 - 子类继承.py
import time
class Kid():
def __init__(self, name = "", sex = "", age = ""):
self.name = name
self.age = age
self.sex = sex
def play(self):
print("玩游戏中...")
class Stu(Kid): #继承 Kid 类
def __init__(self,name = "", sex = "", age = "", score = ""):
Kid.__init__(self, name, sex, age)
self.score = score
def get_score(self):
print(f"{self.name} 的成绩是{self.score}")
def good_good_study(self):
print("好好学习中...")
time.sleep(10)
self.score += 0.1
stu1 = Stu(name = "张三", sex = True, age = 24, score = 59.9)
stu1.play() #能够调用父类中的方法
如果子类中有和父类同名的方法,父类方法将被覆盖;如果需要访问父类的方法,则要调用一个未绑定的父类方法,明确给出子类的实例。
# 07 - 方法重写.py
import time
class Kid():
def __init__(self, name = "", sex = "", age = ""):
self.name = name
self.age = age
self.sex = sex
def play(self):
print("玩游戏中...")
class Stu(Kid):
def __init__(self,name = "", sex = "", age = "", score = ""):
Kid.__init__(self, name, sex, age)
self.score = score
def get_score(self):
print(f"{self.name} 的成绩是{self.score}")
def play(self): # 父类方法重写
print("玩QQ飞车中...")
time.sleep(2) # 添加 2 秒延迟
self.score -=10
def good_good_study(self):
print("好好学习中...")
time.sleep(10)
self.score += 0.1
stu1=Stu(name="张三",sex=True,age=22,score=59.9)
stu1.get_score() # 张三的成绩是59.9
stu1.good_good_study() # 好好学习中...
stu1.get_score() # 张三的成绩是60.0
stu1.play() # 玩QQ飞车中...
stu1.get_score() # 张三的成绩是50.0
说明:
import time
引入了 time 模块,用于添加延时。
__init__()
方法是一个构造函数,用于初始化对象的属性。 Kid.init(self, name, sex, age) 是在 Stu 类的构造函数中调用了 Kid 类的构造函数来初始化从 Kid 类继承的属性。在
Stu
类中新增了一个score
属性,并在__init__()
方法中进行初始化。
Python 允许多重继承,即一个类可以是多个父类的子类,子类可以拥有所有父类的属性。
多继承的格式:
class 子类名(父类1, 父类2, …):
子类中的代码
如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的
# 08 - 多重继承.py
class A:
def get(self):
print("get A")
class B:
def get(self):
print("get B")
class C(A, B):
def __init__(self):
print("class C")
c = C()
c.get()
输出结果:
另一种情况:
class A:
def __init__(self):
print("class A")
class B:
def __init__(self):
print("class B")
class C(A, B):
def get(self):
print("get C")
c = C()
c.get()
输入结果:
继承顺序交换
class A:
def get(self):
print("get A")
class B:
def get(self):
print("get B")
class C(B, A):
def __init__(self):
print("class C")
c = C()
c.get()
输出结果:
不重复的函数
class A:
def get(self):
print("get A")
def func1(self):
print("func1")
class B:
def get(self):
print("get B")
def func2(self):
print("func2")
class C(B, A):
def __init__(self):
print("class C")
def func3(self):
print("func3")
c = C()
c.func1()
c.func2()
c.func3()
输出结果:
函数 | 作用 |
---|---|
issubclass() | 判断一个类是另一个类的子类或子孙类 |
isinstance() | 判定一个对象是否是另一个给定类的实例 |
hasattr() | 判断一个对象是否有一个特定的属性 |
getattr() | 获得一个对象的属性值 |
setattr() | 设置一个对象的属性 |
delattr() | 删除一个对象的属性 |
魔法函数是系统自带的,会在“恰当”的时候自动调用。
基本的魔术方法:
方法 | 说明 |
---|---|
__init__(self) |
初始化方法,当实例被创建的时候调用的初始化方法 |
__call__(self) |
允许一个类的实例像函数一样被调用 |
__str__(self) |
定义当被 str() 调用时的行为 |
__hash__(self) |
定义当被 hash() 调用时的行为 |
__bool__(self) |
定义当被 bool() 调用时的行为,应该返回 True 或 False |
# 09 - 魔术方法.py
class Test():
def __init__(self): #初始化时调用
print("Function __init__ is called!")
def __str__(self): # 对象打印时调用
return "Why print(self)?"
def __call__(self): # 把对象当作函数调用时触发
print("Why call me like Function?")
t = Test()
print("------------------------")
print(t)
print("------------------------")
t()
执行结果:
Python 为类元素(属性和方法)的私有性提供初步的形式,由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许的。
# 10 - 私有化.py
import time
class Stu():
def __init__(self, name, sex, age, score):
self.name = name
self.sex = sex
self.age = age
self.__score = score # 设置 score 为私有的,只有在类的内部访问到 score
def getSocre(self): #我们可以在外部调用内部的getScore方法来访问 Score属性
print(f"{self.name} 的成绩是{self.__score}")
def goodGoodStudy(self):
print("好好学习中...")
time.sleep(10)
self.__score += 0.1
stu2 = Stu(name = "GHUI", sex = True, age = 24, score = 89.9)
# print(stu2.score) #外部不能直接访问类的私有属性
stu2.getSocre() #调用类的内部方法来访问类的私有属性
执行结果: