Python面向对象编程核心笔记:类、对象、继承与多态实战解析
说实话写Python学习笔记这玩意儿我一开始也是随手记写到第四部分“面向对象编程”的时候发现前面那些变量、循环、函数的知识全都在这里开始“串”起来了。如果你的学习路线跟我一样——先是基本语法再是函数然后一头扎进类Class和对象Object——那你大概率也体会过那种“每个字都认识但组合起来不知道干嘛”的懵圈感。这篇文章就是把我自用的这part笔记重新梳理了一遍把当时卡住的地方、琢磨明白的逻辑、还有写代码时踩过的坑全部摊开来讲。不管你是刚看完函数准备进阶还是学完一遍回来查漏补缺这套内容应该都能帮你把OOP面向对象编程这块地基打牢。我的笔记一向不求全面只求“下次看到还能想起来”。所以这篇会直接切入类和对象的核心逻辑配合大量能跑通的代码片段尽量用大白话把抽象概念掰碎了讲。毕竟面向对象这东西光背定义没用你得真的拿它去写点东西才能在脑子里建立起模型。1. 为什么学了基础语法还要专门啃“面向对象”很多时候我们写脚本从第一行写到最后一行的那种“面向过程”写法处理个几百行的逻辑完全够用。但一旦代码量上来或者几个功能模块之间要互相配合面向过程的代码就开始变得像一团乱麻——你改了一个全局变量可能莫名其妙影响了另外一个毫不相干的函数。1.1 面向过程与面向对象的直觉对比面向过程的思路是“我要做什么于是按步骤写下来”。比如模拟一个简单的员工管理系统面向过程的写法可能是# 面向过程思路 name 张三 age 25 position 工程师 def introduce(person_name, person_age, person_position): print(f{person_name}是{person_position}今年{person_age}岁) introduce(name, age, position)这看起来没什么问题但如果有十个员工呢你是不是得写十个变量如果还要记录每个人的工资、绩效、入职时间呢变量一多光命名就够头疼。面向对象则换了个思路把相关的数据和操作这些数据的方法打包在一起形成一个“模板”然后用模板批量创建实例。1.2 三个必懂概念类、对象、实例类Class可以理解为一张图纸定义了有什么属性数据和能做什么事方法。对象Object广义上Python里一切皆对象不过在OOP语境下通常指根据类创建出来的具体实体。实例Instance基于某个类实际创建出来的那个对象。比如“人”是一个类而“站在你面前的张三”就是一个实例。我当年就是没搞懂“对象”和“实例”的区别后来想明白一个特别土的类比类就是“月饼模具”实例就是用模具压出来的“那块月饼”。模具本身不是月饼但它决定了月饼长什么样。Python文档里有时说“对象”有时说“实例”大多数时候指的就是同一个东西——按类创建出来的具体数据实体。注意我一开始犯过的错误是写class Employee:之后忘记加self参数导致调用方法的时候老是报“takes 1 positional argument but 2 were given”。这个self是Python类方法永远的第一个参数它指向当前实例本身千万别漏。2. 类与对象从“图纸”到“实体”的映射这一部分是OOP的地基搞清楚类里面的变量和方法到底怎么定义、怎么调用后面继承、多态学起来才会顺。我自己学的时候发现难点集中在__init__方法、实例属性与类属性的区别还有方法第一个参数self的理解上。2.1 定义第一个类理解init到底在干什么直接上代码这是我笔记里最精简的员工类版本class Employee: 员工类记录基本信息并提供自我介绍方法 company 某某科技有限公司 # 类属性 def __init__(self, name, age, position): self.name name # 实例属性 self.age age self.position position def introduce(self): 类内部的方法第一个参数必须是self print(f我是{self.name}职位{self.position}今年{self.age}岁) # 实例化根据类创建具体员工 emp1 Employee(李四, 28, 测试工程师) emp1.introduce() # 访问属性 print(emp1.name) print(emp1.company) # 访问类属性__init__是一个特殊方法它的中文翻译叫“构造函数”或者“初始化方法”但我更愿意叫它“入场设定”——每次你创建一个新实例Python会自动调用它把接收到的参数绑定到实例身上。请注意__init__里的第一个参数self不用你传Python会自动把 emp1 这个实例本身传进去。2.2 实例属性与类属性极易踩坑的赋值细节上面的代码里company定义在__init__外面叫类属性所有实例共享这个值。而self.name这种定义在__init__里面、用self.前缀的叫实例属性每个实例各自独立。有个坑特别容易踩如果你通过实例给类属性赋值实际上不是修改类属性而是给这个实例创建了一个新的实例属性把类属性“遮住”了。看这个例子emp1 Employee(李四, 28, 测试工程师) emp2 Employee(王五, 30, 开发工程师) emp1.company 另一家公司 # 这里只是给emp1创建了实例属性 print(emp1.company) # 另一家公司 print(emp2.company) # 某某科技有限公司 Employee.company 集团总部 # 直接通过类修改类属性 print(emp2.company) # 集团总部想改类属性就通过类去改别通过实例去改。这是我当时记在笔记第一行的话现在每次写类都会下意识检查一下属性定义的位置。3. 继承与多态让代码少写一半的关键玩法面向对象最大的好处不是把数据和函数绑在一起而是能在类与类之间建立关系。继承就是最典型的例子——子类可以复用父类的代码也可以覆盖父类的方法这比复制粘贴省了太多事。3.1 单继承、多继承与MRO单继承很好理解子类只有一个父类。看这个样例在Employee基础上搞一个Manager子类class Manager(Employee): 经理类继承自Employee额外多一个管理职责字段 def __init__(self, name, age, position, department): super().__init__(name, age, position) # 调用父类的初始化方法 self.department department def introduce(self): # 先复用父类的逻辑再补充自己的信息 super().introduce() print(f我管理{department}部门) mgr Manager(赵六, 35, 项目经理, 研发部) mgr.introduce()这里的super()是新手很容易忽略但极其重要的一个点它用来调用父类的方法。如果不写super().__init__(...)那么name、age、position这些在父类__init__里定义的属性就不会被初始化子类实例访问时就报AttributeError。Python支持多继承但多继承一旦用不好就会出现找方法顺序混乱的问题。Python通过MROMethod Resolution Order规则决定先找哪个父类。简单说多继承时顺序是“广度优先”先用类名.__mro__查看查找顺序class A: def say(self): print(A) class B(A): def say(self): print(B) class C(A): def say(self): print(C) class D(B, C): pass d D() d.say() # 输出 B print(D.__mro__) # 查看方法解析顺序D的MRO顺序是 D - B - C - A - object。所以调用say()时会先找到B的。多继承不是不能用但尽量少用真要用的话理清MRO顺序再动手。我自己在项目里多继承用了三次每次都要靠打印__mro__来确认不然真的容易晕。3.2 重写方法与多态同一个方法名不同表现子类可以重新实现父类的方法这叫重写/覆盖override。重写之后同样的方法名在不同类里就有不同的表现这就引出了多态polymorphism。class Developer(Employee): def coding(self): print(f{self.name} 正在写代码) class QA(Employee): def testing(self): print(f{self.name} 正在测试) employees [Developer(张三, 25, 开发), QA(李四, 28, 测试)] for emp in employees: emp.introduce() # 多态调用的都是introduce但结果会根据实例类型不同而不同严格来说Python的多态不用死记定义因为Python本身就是动态语言天然支持“鸭子类型”——只要一个对象有introduce方法不管它是哪个类的实例调用起来都没问题。你不用像Java那样刻意去写接口或抽象类写Python的时候“看起来像用起来像那它就是”。4. 封装、私有成员与属性装饰器封装Encapsulation是OOP三大特性之一说白了就是“把数据藏起来只给你提供有限的访问入口”。但实际上Python在语言层面没有一个强制的“private”关键字它的私有是靠命名约定和名称改写机制实现的。4.1 单下划线与双下划线的真实区别我在笔记里专门写了一段来区分这两种写法_name单下划线开头约定俗成表示“这是内部变量外部不要直接访问”但如果你非要去访问程序也不会拦你。__name双下划线开头Python解释器会做名称改写name mangling把它变成_ClassName__name直接外部访问会报错但通过改写后的名字依然能访问。class Person: def __init__(self, name, secret): self.name name self._internal 内部变量 self.__private secret p Person(测试, 秘密信息) print(p.name) # 正常 print(p._internal) # 能访问但不建议 # print(p.__private) # 报错AttributeError # 但强制访问还是可以的 print(p._Person__private) # 秘密信息所以Python的封装更多是“君子协定”它给你提供了隐藏的便利但不会像其他语言那样严格禁止外部访问。我个人建议写类的时候不想让外部直接改的属性就用双下划线开头只是想表达“内部使用”的用单下划线就行。过度使用双下划线反而会让调试变麻烦。4.2 property把方法像属性一样访问说实话刚学property的时候我没觉得它有多大用后来写一个带校验的类才发现真香。它可以让你把一些本该是私有变量的数据通过方法去做逻辑判断但外部调用时却像访问属性一样自然。class Student: def __init__(self, name, score): self.name name self._score score property def score(self): 获取成绩 return self._score score.setter def score(self, value): 设置成绩带校验逻辑 if not 0 value 100: raise ValueError(成绩必须在0-100之间) self._score value s Student(小明, 85) print(s.score) # 像属性一样访问 s.score 95 # 像属性一样赋值但走的是setter里的校验逻辑 # s.score 120 # 会抛出 ValueError这样做的好处是以后如果要加日志、加校验、加数据监控只需要在setter里面加代码外部调用的代码完全不用改。这个模式在项目里非常实用尤其是处理配置类、数据模型类的时候。5. 几个高频特殊方法str、repr、eqPython的类里有一批“双下划线方法”也叫魔法方法。不一定要全部记住但有几个是写代码时几乎每天都会碰到的。把它们弄明白调试效率能提升一倍。5.1str与repr打印对象时不只想看到内存地址如果你不加__str__直接打印一个实例输出的是类似__main__.Employee object at 0x7f9a1c0c0d30这样的东西看着完全不知道里面是什么。加了这个方法后打印出来就能直接看到关键信息。class Employee: def __init__(self, name, age): self.name name self.age age def __str__(self): return fEmployee(name{self.name}, age{self.age}) def __repr__(self): return fEmployee({self.name}, {self.age}) emp Employee(测试, 18) print(emp) # 调用 __str__ print(repr(emp)) # 调用 __repr____str__面向用户给人看的__repr__面向开发者最好能返回一个“重建这个对象”的表达式。两个都写上是专业写法。实际调试的时候在IDE里展开变量列表显示的就是__repr__的返回值。5.2eq自定义对象比较规则直接用比较两个自定义对象默认比较的是内存地址即使两个对象内部数据完全一样结果也是False。这时候就需要重写__eq__class Employee: def __init__(self, name, age): self.name name self.age age def __eq__(self, other): if isinstance(other, Employee): return self.name other.name and self.age other.age return False a Employee(张三, 25) b Employee(张三, 25) print(a b) # True我见过不少初学者在比较两个对象时发现明明数据一样却返回False就在那纠结半天。其实原理就是没重写__eq__。记住Python不会自动帮你判断两个对象“内容是否相等”这个规则要你自己定义。6. 学习过程中踩过的坑与排查技巧学OOP的过程我犯过的错误比记下的知识点还多。这里整理几个典型的坑希望能帮你少走弯路。6.1 方法里忘了self参数错位初学者最容易遇到的是定义方法时没写self然后调用emp.introduce()时Python会把emp自动作为第一个参数传进去导致“本来想传name的结果传了个对象进去”。解决办法很简单定义实例方法时第一个参数一律写self没得商量。class BrokenExample: def __init__(self): self.name test def wrong_method(name): # 错误缺少self print(name) b BrokenExample() # b.wrong_method() # TypeError: wrong_method() takes 1 positional argument but 2 were given class FixedExample: def __init__(self): self.name test def ok_method(self): print(self.name)6.2 继承时忘了调用 super().init子类定义了__init__后如果忘了调用super().__init__()父类里初始化的属性全部不存在。这个坑出现得极其隐蔽因为有时候子类恰好不需要父类的属性代码也能跑。但一旦你后面又有新需求比如打印父类里某个属性就露馅了。class Parent: def __init__(self): self.name 父类名称 class Child(Parent): def __init__(self): # 忘记 super().__init__() self.age 10 c Child() print(c.age) # 10 # print(c.name) # AttributeError: Child object has no attribute name所以我的习惯是子类里只要写了__init__第一行就是super().__init__(...具体的参数...)没有例外。6.3 共享可变对象当默认参数这个坑其实不算OOP专属但在类方法里特别常见。不要在方法定义时用可变对象当默认参数比如def method(self, items[])。因为默认参数只会在定义时创建一次多个实例共用同一个列表。class Bad: def __init__(self, items[]): self.items items a Bad() b Bad() a.items.append(新元素) print(b.items) # [新元素]因为a和b用的是同一个列表对象 class Good: def __init__(self, itemsNone): self.items items if items is not None else [] c Good() d Good() c.items.append(新元素) print(d.items) # []这个错误的隐蔽性在于代码能跑结果看起来也“好像没问题”直到某一天多实例互相影响数据才追查到源头。正确写法就是上面Good类的写法可变默认参数一律先给None再在方法内部重新创建。7. 自用过程中的一点补充心得面向对象编程的知识点其实远不止这些比如类方法classmethod、静态方法staticmethod、抽象类、描述符、元类每一个都是一大块内容。但说实话这些属于进阶玩法日常写脚本、处理数据、爬虫、写小工具前面这几节内容已经能搞定绝大部分需求。我自己的学习路径是这样的先把类、实例、属性、方法、继承这几个核心概念用代码写熟每一个概念都写一个小例子跑通。然后找个完整的项目练手比如用Employee类去写一个简单的薪资计算器或者用Student类去管理成绩比单纯看知识点有效得多。我第一次觉得OOP“开窍”不是看书看懂的而是写了一个游戏角色类里面有血条、攻击、防御这些属性和方法之后突然就明白了“为什么要把数据和操作绑在一起”。最后分享一个我在写类的时候固定使用的小习惯每个类写完都顺手加上__str__和__repr__哪怕只是简单返回关键属性。这能让你在调试的时候少浪费很多时间。还有一个习惯是类与类之间的继承关系别超过三层超过三层之后代码的阅读难度会指数级上升除非有特别强的理由否则用组合代替继承会更清晰。记住一个判断标准**“是”关系用继承“有”关系用组合。**比如“经理是一个人”适合继承“汽车有一个引擎”适合组合。这条原则能解决大部分设计上的纠结。

相关新闻

DeepSeek V4.1 Pro测试聚焦Harness:本地部署与Agent编排实战

DeepSeek V4.1 Pro测试聚焦Harness:本地部署与Agent编排实战

1. 从一条测试消息说起:DeepSeek V4.1 Pro 到底在测什么 国庆前一周,几个技术群里同时冒出一条消息:DeepSeek V4.1 Pro 已经进入测试阶段,有望在国庆期间发布。消息本身很短,但底下跟的讨论量不小,因为这次…

2026/10/2 22:33:49 阅读更多 →
矩形波导TE10仿真设计与电磁场分析:从截止频率到HFSS建模验证

矩形波导TE10仿真设计与电磁场分析:从截止频率到HFSS建模验证

简介:面向电磁场与微波技术课程实验,包含1个doc文档(约258KB),围绕矩形波导TE10模式,系统梳理导波原理、TE10场结构与HFSS仿真分析流程,适合高校学生及HFSS初学者用于实验预习、报告撰写与课程复…

2026/10/2 22:33:49 阅读更多 →
基于SSM框架的图书馆预约管理系统设计与实现

基于SSM框架的图书馆预约管理系统设计与实现

期末图书馆一座难求,占座乱象更是常态。我接手过不少类似的管理需求,最后都落在 SSM框架 上。这套 图书馆预约管理系统 (编号09509)是我个人认为特别适合用来做课程设计或毕设复盘的项目,因为它把“预约-签到-释放…

2026/10/2 22:33:49 阅读更多 →

最新新闻

终端 command not found 之谜:PATH 环境变量与 VS Code/Cursor 修复全指南

终端 command not found 之谜:PATH 环境变量与 VS Code/Cursor 修复全指南

从终端里敲code .却收到command not found,这个场景我见过太多次了。尤其是在 macOS 上,刚装完 VS Code,兴冲冲想在终端里打开项目,结果 shell 根本不认识这个命令;Cursor 也一样,cursor .按下去&#xff0…

2026/10/2 23:12:34 阅读更多 →
2025 NIPS Attractive Metadata Attack 复现:让 LLM Agents 误调恶意工具的元数据陷阱与防御验证

2025 NIPS Attractive Metadata Attack 复现:让 LLM Agents 误调恶意工具的元数据陷阱与防御验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 23:11:34 阅读更多 →
5 分钟搭建本地 AI 助手 OpenClaw 全平台部署实操:TaoToken 统一 Key 接入 Win11 与多端配置

5 分钟搭建本地 AI 助手 OpenClaw 全平台部署实操:TaoToken 统一 Key 接入 Win11 与多端配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 23:11:34 阅读更多 →
Google Antigrgravity 支持 Agent Skills:用 SKILL.md 把 AI 编程工作流接进 TaoToken

Google Antigrgravity 支持 Agent Skills:用 SKILL.md 把 AI 编程工作流接进 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 23:11:34 阅读更多 →
牛逼干货分享!OpenClaw Workspace 运维实战手册:把 settings 改到 TaoToken 的排障清单

牛逼干货分享!OpenClaw Workspace 运维实战手册:把 settings 改到 TaoToken 的排障清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 23:11:34 阅读更多 →
PyCharm高效插件精选指南:2026年最强插件搭配TaoToken统一Key提效300%

PyCharm高效插件精选指南:2026年最强插件搭配TaoToken统一Key提效300%

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 23:11:34 阅读更多 →

日新闻

从零搭建AI工程化:模型之外的完整闭环

从零搭建AI工程化:模型之外的完整闭环

先搞清楚一件事:从零开始做 AI 工程化,难的从来不是调模型、写提示词,而是把一套原型 Demo 变成长得像是“正经系统”的东西。你手里可能已经有了能跑通的代码,也可能刚读完一些概念,但真到了要把它变成可维护、可观测…

2026/10/2 0:00:20 阅读更多 →
大模型训练显存估计与混合精度训练实战指南

大模型训练显存估计与混合精度训练实战指南

1. 大模型训练显存估计与混合精度训练详解显存不够用,几乎是每个做大模型训练的人都会撞上的第一堵墙。你可能也经历过:模型代码写完了,数据管道跑通了,满心欢喜地按下训练启动脚本,结果几秒钟后终端弹出一行红字——C…

2026/10/2 0:00:20 阅读更多 →
小样本学习数据集选型指南:27个真正可用的高质量数据集

小样本学习数据集选型指南:27个真正可用的高质量数据集

1. 小样本学习的“弹药库”:为什么你总在找数据集,却总找不到真正能用的? 小样本、数据集——这两个词最近半年在我处理的200多个AI项目咨询里,出现频率排进前三。不是模型调不好,不是代码写不对,而是卡在…

2026/10/2 0:00:20 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 19:40:48 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/1 19:41:40 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/10/1 20:05:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 5:26:06 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 6:09:11 阅读更多 →