news 2026/5/13 11:52:13

【Python基础 | 第5章】面向对象与异常处理:一文搞懂类、对象、封装、继承、多态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Python基础 | 第5章】面向对象与异常处理:一文搞懂类、对象、封装、继承、多态

目录名称

    • 前言
    • 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)# 4

2. 异常

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 基础》,一起把基础打牢。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/13 16:22:56

OpenClaw故障演练:gemma-3-12b-it在断网环境下的降级策略

OpenClaw故障演练&#xff1a;gemma-3-12b-it在断网环境下的降级策略 1. 为什么需要断网演练 上周我在用OpenClaw自动处理一批市场分析报告时&#xff0c;遇到了突发网络中断。当时正在运行的gemma-3-12b-it模型突然失去响应&#xff0c;导致整个自动化流程卡死。这次意外让我…

作者头像 李华
网站建设 2026/4/17 18:34:20

微信网页版浏览器插件:轻量化办公通讯解决方案

微信网页版浏览器插件&#xff1a;轻量化办公通讯解决方案 【免费下载链接】wechat-need-web 让微信网页版可用 / Allow the use of WeChat via webpage access 项目地址: https://gitcode.com/gh_mirrors/we/wechat-need-web 在数字化办公环境中&#xff0c;即时通讯工…

作者头像 李华
网站建设 2026/4/15 12:17:04

2026 最强 AI 毕业论文工具合集:9 大神器从选题到答辩一站式通关

一、毕业季突围&#xff1a;AI 论文工具成本科生刚需&#xff0c;选对才是关键 每到毕业季&#xff0c;毕业论文就成了横亘在学子与毕业之间的最大难关。从选题时的迷茫无措&#xff0c;到文献搜集的繁琐耗时&#xff1b;从写作时的逻辑混乱、内容空洞&#xff0c;到降重阶段的…

作者头像 李华