目录名称
- 前言
- 1. 面向对象
- 1.1 面向对象基础
- 1.2 封装
- 1.3 继承
- 1.4 多态
- 1.5 魔法方法
- 1.6 实例属性与类属性
- 2. 异常
- 2.1 定义
- 2.2 异常处理
- 2.3 异常的传递
- 结语
🎬 博主名称:超级苦力怕
🔥 个人专栏:《Python 基础》
🚀 每一次思考都是突破的前奏,每一次复盘都是精进的开始!
前言
本文是 Python 基础系列的核心篇章,系统讲解面向对象编程(类、对象、封装、继承、多态、魔法方法、类属性与实例属性)以及异常处理机制。
1. 面向对象
1.1 面向对象基础
面向过程:把一个需求分解成一系列要执行的步骤,然后依次执行(关注流程、步骤),适合简单、线性的任务。
类:一组具有相同属性(特征)和方法(功能/行为)的模板。
对象:面向对象编程的基本单元,是类的实例,将数据和操作打包在一起。
提示:对象是由类创建出来的,一个类可以创建无数个对象,创建对象的过程也叫对象的实例化。
# 定义类class类名:def__init__(self,参数列表):# 函数定义在类里,叫方法self.属性名=参数值# 变量定义在类里,叫属性self.属性名=参数值def方法名(self,形参列表):# 方法体pass# 创建对象对象名=类名(参数值1,参数值2)示例:
classCar:def__init__(self,brand,name,price):self.brand=brand self.name=name self.price=pricedefrunning(self):print(f"{self.brand}{self.name}正在行驶...")# 创建对象c1=Car("BMW","X5",500000)c1.running()说明:
- 类名采用大驼峰命名法,每个单词首字母都是大写,单位之间没有分隔符(如
UserAccount)。__init__是初始化方法,在对象创建时自动调用,用于初始化属性;self代表当前实例,调用时无需传递。- 通过
对象.属性或对象.方法()访问成员。
1.2 封装
封装:将数据(属性)和操作数据的方法(行为)包装在类内部,对外隐藏实现细节,只暴露必要的接口。通过控制属性的访问权限,保证数据安全。
Python 中没有严格的访问控制,通常使用单下划线_或双下划线__表示“受保护的”或“私有的”属性,并提供getter/setter方法
classBankAccount:def__init__(self,owner,balance):self.owner=owner self.__balance=balance# 私有属性# getter 方法:获取余额defget_balance(self):returnself.__balance# setter 方法:修改余额(带校验)defset_balance(self,amount):ifamount<0:print("余额不能为负数")returnself.__balance=amountdefdeposit(self,amount):ifamount>0:self.__balance+=amountprint(amount)# 仅打印存入金额else:print("存款金额必须为正数")defwithdraw(self,amount):if0<amount<=self.__balance:self.__balance-=amountprint(amount)# 仅打印取出金额else:print("余额不足或金额无效")# 存钱acc=BankAccount("张三",1000)acc.deposit(500)# 输出: 500acc.withdraw(200)# 输出: 200print(acc.get_balance())# 输出: 1300# 通过 setter 修改余额acc.set_balance(2000)print(acc.get_balance())# 输出: 2000# 尝试直接访问私有属性会报错(但可通过特殊方式访问,不推荐)# print(acc.__balance) # AttributeError拓展: 也可以使用@property装饰器来实现封装
@property:定义 getter 方法,当我们获取 balance 的时候,会自动执行这个方法,返回self.__balance@balance.setter:定义 setter 方法,当执行 acc.balance = 2000 时,会自动调用该方法,将等号右边的值传入。
classBankAccount:def__init__(self,owner,balance):self.owner=owner self.__balance=balance@propertydefbalance(self):returnself.__balance@balance.setterdefbalance(self,amount):ifamount<0:print("余额不能为负数")returnself.__balance=amountdefdeposit(self,amount):ifamount>0:self.__balance+=amountprint(amount)else:print("存款金额必须为正数")defwithdraw(self,amount):if0<amount<=self.__balance:self.__balance-=amountprint(amount)else:print("余额不足或金额无效")# ---------- 使用示例(补充) ----------acc2=BankAccount("李四",2000)print(acc2.balance)# 通过属性直接获取余额,输出 2000acc2.balance=3000# 通过属性直接设置余额(调用 setter)print(acc2.balance)# 输出 3000acc2.deposit(500)# 输出 500print(acc2.balance)# 输出 3500注意:
- 封装是一种约定和防意外的机制,并非严格的安全保障
- 封装的好处:通过 getter/setter 控制数据读写逻辑,避免外部直接赋值无效值,同时可以在内部进行数据校验、类型转换、以及触发其他操作,提高代码可维护性。
1.3 继承
继承:子类可以继承父类的属性和方法,实现代码复用,并可以在子类中扩展或重写父类的功能。
# 父类classVehicle:def__init__(self,brand,model):self.brand=brand self.model=modeldefstart(self):print(self.brand,self.model,"启动...")# 子类classCar(Vehicle):def__init__(self,brand,model,doors):super().__init__(brand,model)# 调用父类构造方法self.doors=doorsdefhonk(self):print(self.brand,self.model,"鸣笛:滴滴~")# 使用car=Car("BMW","X5",4)car.start()# 输出:BMW X5 启动...car.honk()# 输出:BMW X5 鸣笛:滴滴~方法重写:子类可以重新定义父类中的方法,提供自己的实现。
classElectricCar(Car):def__init__(self,brand,model,doors,battery):super().__init__(brand,model,doors)self.battery=battery# 重写 start 方法defstart(self):print(self.brand,self.model,"无声启动,电量",self.battery,"kWh")e_car=ElectricCar("Tesla","Model 3",4,75)e_car.start()# 输出:Tesla Model 3 无声启动,电量 75 kWh注意:
super()用于调用父类的方法,确保父类的初始化逻辑被执行。- Python 支持多重继承(一个子类可继承多个父类),但复杂场景下容易引发问题,建议谨慎使用。
1.4 多态
多态:同一操作作用于不同对象时,可以产生不同的执行结果。它允许使用统一的方式处理不同类型的对象,提高代码的灵活性和可扩展性。
defvehicle_test(vehicle):"""统一接口,不同对象表现出不同行为"""vehicle.start()# 创建不同类型的对象vehicles=[Car("Audi","A6",4),ElectricCar("Tesla","Model 3",4,75)]forvinvehicles:vehicle_test(v)# 自动调用各自类中的 start 方法多态的实现不依赖特殊的语法,只需保证不同类中有相同名称的方法即可。Python 进一步强化了多态:只要对象有需要的方法,就可以当作所需类型使用。
classBicycle:defstart(self):print("自行车开始骑行")vehicles.append(Bicycle())vehicle_test(vehicles[-1])# 输出:自行车开始骑行1.5 魔法方法
魔法方法(特殊方法)是以双下划线开头和结尾的方法,Python 会在特定场景下自动调用,用于定义类的特殊行为。
| 魔法方法 | 描述 |
|---|---|
__init__(self, ...) | 构造方法,创建对象时自动调用 |
__str__(self) | 定义print(对象)或str(对象)的输出内容 |
__repr__(self) | 定义对象的官方字符串表示,常用于调试 |
__eq__(self, other) | 定义==操作符的行为 |
__lt__(self, other) | 定义<操作符的行为,其他比较操作符类似 |
__len__(self) | 定义len(对象)的行为 |
__getitem__(self, key) | 定义通过索引或键访问元素的行为 |
示例:
classStudent:def__init__(self,name,score):self.name=name self.score=scoredef__str__(self):returnf"学生:{self.name},成绩:{self.score}"def__eq__(self,other):returnself.score==other.scoredef__lt__(self,other):returnself.score<other.score s1=Student("张三",85)s2=Student("李四",92)print(s1)# 输出:学生:张三,成绩:85print(s1==s2)# Falseprint(s1<s2)# True注意:魔法方法不需要手动调用,Python 在相应操作发生时自动调用它们。
1.6 实例属性与类属性
- 实例属性:属于每个具体对象,通过
self定义,每个对象独立拥有。 - 类属性:属于类本身,所有实例共享,通过类名或
self.__class__访问,常用于配置或共享数据。
classCar:# 类属性(所有实例共享)wheels=4tax_rate=0.1def__init__(self,brand,name,price):# 实例属性(每个对象独立)self.brand=brand self.name=name self.price=pricedeftotal_cost(self):# 访问实例属性 price 和类属性 tax_ratereturnself.price*(1+Car.tax_rate)# 访问类属性print(Car.wheels)# 4c1=Car("BMW","X5",500000)c2=Car("Audi","A6",450000)print(c1.wheels)# 4(通过实例也能访问类属性)print(c2.total_cost())# 495000.0# 修改类属性会影响所有实例Car.tax_rate=0.12print(c1.total_cost())# 560000.0查找顺序:当通过实例访问属性时,Python 会先查找实例属性,如果不存在则查找类属性。实例属性会“遮盖”同名的类属性,但类属性本身不会被修改。
c1.wheels=3# 为实例 c1 添加实例属性 wheels,不会影响类属性print(c1.wheels)# 3print(Car.wheels)# 4print(c2.wheels)# 42. 异常
2.1 定义
异常:程序运行过程中出现的错误,会中断程序的正常执行流程
作用:
- 保证数据、逻辑正确性,避免程序执行混乱
- 在开发阶段,尽量发现更多问题,尽早解决,保障程序正常执行
2.2 异常处理
程序运行过程出现异常,我们可以选择不做处理或捕获异常,如果我们捕获并处理异常,程序会继续执行(编写程序做好预案,出现异常按预案处理)。
当程序处于 try 语句内报错,会从上至下匹配,直到匹配成功,进行解决,程序继续运行
# 定义语法try:可能出现异常的业务代码1可能出现异常的业务代码2...except[异常类型as变量名]出现异常时预案finally:不管是否出现异常都会执行的代码# 示例try:print("=")print(my_name)# 这里没有定义该变量,会被捕获print("=")exceptNameErrorase:print("程序运行报错,错误信息:",e)finally:print("释放资源 ~")2.3 异常的传递
一场传递就是异常在函数调用中层层上报的过程,直到有人处理它或程序崩溃
deffun1():print("fun1 ... running ...")fun2()# 调用fun2,异常会从这里传递上去deffun2():print("fun2 ... running ...")fun3()# 调用fun3,异常会从这里传递上去deffun3():print("fun3 ... running ...")print(my_color)# NameError: name 'my_color' is not defined,异常在这里发生if__name__=='__main__':fun1()# 调用fun1,异常会沿着调用链传递到这里结语
本文全面讲解了 Python 面向对象编程(类、对象、封装、继承、多态、魔法方法、属性分类)以及异常处理的核心知识。通过这篇文章,能够理解如何设计类、控制访问、复用代码、处理运行时错误。
- 如果本文对你有帮助:欢迎点赞、收藏,让更多正在学 Python 的同学看到。
- 遇到问题或有不同理解:可以在评论区留言,一起讨论、互相学习。
- 想系统看更多内容:可以关注专栏《Python 基础》,一起把基础打牢。