news 2026/10/15 18:48:26

【Python】基础语法入门(十六)——面向对象编程(OOP)核心精讲

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Python】基础语法入门(十六)——面向对象编程(OOP)核心精讲


🧱说明:虽然面向对象(OOP)在早期章节已有初步介绍,但因其重要性,本篇作为系统性回顾与深化,聚焦 OOP 四大支柱(封装、抽象、继承、多态)及 Python 特色实现。你将学会如何用类(Class)优雅地建模现实世界,写出可维护、可扩展的代码。

无论你是初学 OOP,还是想夯实基础,本文都将助你:

  • 理解self的本质
  • 掌握属性与方法的设计
  • 合理使用继承与多态
  • 避开常见陷阱

1. 为什么需要面向对象?

过程式编程的局限

# 模拟两个学生name1="小明"age1=18grade1="高一"name2="小红"age2=17grade2="高二"defprint_student(name,age,grade):print(f"{name},{age}岁,{grade}")

❌ 问题:数据与行为分离,难以扩展,易出错(如传参顺序错乱)。

面向对象的解决方案

classStudent:def__init__(self,name,age,grade):self.name=name self.age=age self.grade=gradedefintroduce(self):print(f"{self.name},{self.age}岁,{self.grade}")s1=Student("小明",18,"高一")s2=Student("小红",17,"高二")s1.introduce()

✅ 优势:数据 + 行为 封装在一起,逻辑清晰,易于复用。


2. 类与对象:核心概念

概念说明
类(Class)蓝图或模板(如“学生”这个概念)
对象(Object/Instance)类的具体实例(如“小明”这个学生)
属性(Attribute)对象的数据(name,age)
方法(Method)对象的行为(introduce())

__init__与self

  • __init__:构造方法,创建对象时自动调用
  • self:代表当前实例,必须作为第一个参数

🔍self的本质:
当你调用s1.introduce(),Python 实际执行的是Student.introduce(s1)。
self就是那个隐式传入的s1!


3. 封装(Encapsulation):隐藏内部细节

通过私有属性/方法限制外部直接访问,提供公共接口。

Python 的“私有”约定

  • 单下划线_x:受保护(约定不直接访问)
  • 双下划线__x:名称改写(真正隐藏)
classBankAccount:def__init__(self,owner,balance=0):self.owner=owner self.__balance=balance# 私有属性defdeposit(self,amount):ifamount>0:self.__balance+=amountelse:raiseValueError("存款金额必须为正")defget_balance(self):returnself.__balance# 通过方法安全访问acc=BankAccount("Alice")acc.deposit(100)print(acc.get_balance())# 100# print(acc.__balance) # ❌ AttributeError!print(acc._BankAccount__balance)# ⚠️ 技术上可行,但绝不推荐!

✅最佳实践:用property提供更优雅的访问(见下文)。


4. 继承(Inheritance):代码复用

子类继承父类的属性和方法,并可扩展或重写。

示例:学生与研究生

classStudent:def__init__(self,name,student_id):self.name=name self.student_id=student_iddefstudy(self):print(f"{self.name}正在学习")classGraduateStudent(Student):# 继承 Studentdef__init__(self,name,student_id,advisor):super().__init__(name,student_id)# 调用父类构造self.advisor=advisordefresearch(self):print(f"{self.name}在{self.advisor}指导下做研究")grad=GraduateStudent("李华","G123","张教授")grad.study()# 继承自 Studentgrad.research()# 自有方法

🔑super():安全调用父类方法,支持多重继承。


5. 多态(Polymorphism):同一接口,不同实现

不同类的对象对同一方法做出不同响应。

示例:动物叫声

classAnimal:defspeak(self):raiseNotImplementedError("子类必须实现 speak 方法")classDog(Animal):defspeak(self):return"汪汪!"classCat(Animal):defspeak(self):return"喵喵~"defmake_animal_speak(animal):print(animal.speak())# 同一接口,不同行为make_animal_speak(Dog())# 汪汪!make_animal_speak(Cat())# 喵喵~

✅优势:make_animal_speak不关心具体类型,只要实现了speak即可。


6. 特殊方法(Magic Methods / Dunder Methods)

以双下划线包围的方法,用于定义类的内置行为。

方法作用示例
__str__print(obj)时的字符串表示return f"学生: {self.name}"
__repr__开发者调试用的“官方”字符串return f"Student('{self.name}')"
__len__支持len(obj)return len(self.items)
__eq__支持==比较return self.id == other.id
__add__支持+运算return Vector(self.x+other.x, ...)

示例:让自定义类支持len()和print()

classBookshelf:def__init__(self,books):self.books=booksdef__len__(self):returnlen(self.books)def__str__(self):returnf"书架上有{len(self)}本书"def__repr__(self):returnf"Bookshelf({self.books!r})"shelf=Bookshelf(["Python入门","算法导论"])print(len(shelf))# 2print(shelf)# 书架上有 2 本书

💡黄金法则:

  • __str__面向用户,要友好
  • __repr__面向开发者,要明确(理想情况下eval(repr(obj)) == obj)

7.@property:将方法变为属性

让 getter/setter 更自然,同时保持封装。

classCircle:def__init__(self,radius):self._radius=radius@propertydefradius(self):returnself._radius@radius.setterdefradius(self,value):ifvalue<0:raiseValueError("半径不能为负")self._radius=value@propertydefarea(self):return3.14159*self._radius**2c=Circle(5)print(c.radius)# 5(像访问属性)print(c.area)# 78.53975(只读属性)c.radius=10# 触发 setter,自动校验

✅优势:外部无需知道radius是计算属性还是存储属性。


8. 常见误区与最佳实践

误区正确做法
滥用继承(“继承一切”)优先组合(Composition),而非继承
忽略__init__中的super()多重继承时必须调用
所有属性都公开用property或私有属性控制访问
不写文档字符串为类和方法添加"""说明"""
过度设计先写简单类,再根据需求重构

组合优于继承示例

# ❌ 不好的继承classBird:deffly(self):passclassPenguin(Bird):# 企鹅不会飞!deffly(self):raiseNotImplementedError# ✅ 更好的组合classFlyer:deffly(self):print("Flying!")classBird:def__init__(self,can_fly=True):self.flyer=Flyer()ifcan_flyelseNonedeffly(self):ifself.flyer:self.flyer.fly()else:print("我不会飞 😢")

9. 总结:OOP 设计原则

  1. 单一职责:一个类只负责一件事
  2. 开闭原则:对扩展开放,对修改关闭
  3. 里氏替换:子类对象能替换父类对象
  4. 依赖倒置:依赖抽象,而非具体实现

🐍记住:OOP 是工具,不是目的。
“当你的问题适合用对象建模时,才使用 OOP。”


下一步练习

  1. 为你的 To-Do List 项目设计类结构:
    • Task类(含标题、状态、创建时间)
    • TaskManager类(管理任务列表,支持增删查改)
  2. 为Task添加__str__和__repr__
  3. 用@property实现is_completed只读属性

✨当你能用类清晰表达业务逻辑时,你就真正掌握了 Python 的力量。

继续构建你的对象世界吧!

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

从朦胧到清晰:AI元人文构想的演进脉络与现实路径

从朦胧到清晰&#xff1a;AI元人文构想的演进脉络与现实路径导言&#xff1a;一段思想的成长史【AI元人文&#xff1a;规则与人文的统一及其实现挑战】阅读岐金兰85天前的这篇奠基之作&#xff0c;犹如聆听一场思想的源起。那时的“AI元人文”构想已蕴含着今天所有讨论的核心种…

作者头像 李华
网站建设 2026/10/15 13:56:14

【Linux C/C++开发】Linux 环境下 C/C++ 程序 strip 命令使用指南

Linux 环境下 C/C 程序 strip 命令使用指南 本文档基于 Linux 内核和 GNU 工具链环境&#xff0c;深度解析 strip 命令的技术原理&#xff0c;并提供完整的实战操作指南。 文章目录Linux 环境下 C/C 程序 strip 命令使用指南[toc]1. 技术原理深度解析1.1 ELF 文件与符号表结构…

作者头像 李华
网站建设 2026/10/15 18:41:01

邪修版——MDK 工程结构菜鸟快速入门实战指南(上)

前言在嵌入式开发领域&#xff0c;MDK&#xff08;Keil Microvision&#xff09;作为 STM32 芯片的核心开发环境&#xff0c;其工程结构的规范性直接决定了项目的可维护性、可扩展性与开发效率。对于新手而言&#xff0c;面对复杂的文件夹层级、多样的文件类型以及不同的工程搭…

作者头像 李华
网站建设 2026/10/14 18:52:11

Wan2.2-T2V-A14B如何实现服装材质的真实感渲染?

Wan2.2-T2V-A14B如何实现服装材质的真实感渲染&#xff1f; 在时尚广告的拍摄现场&#xff0c;导演常常为了捕捉一条丝绸裙摆随风轻扬的瞬间&#xff0c;反复调整灯光、风速和模特步伐。这种对细节极致追求的背后&#xff0c;是高昂的时间与人力成本。如今&#xff0c;随着AIGC…

作者头像 李华
网站建设 2026/10/15 18:10:25

多模态大模型技术突破:Qwen3-VL全系列深度解析与本地化部署指南

在人工智能多模态交互领域&#xff0c;Qwen3-VL系列模型的发布标志着视觉语言融合技术进入全新阶段。作为当前业界领先的多模态大模型&#xff0c;该系列通过创新架构设计与训练方法&#xff0c;实现了从图像理解到代码生成、从空间感知到长视频分析的全方位能力跃升。本文将系…

作者头像 李华