Python 函数和类到底怎么选?新手彻底搞懂「面向对象」
写函数写得好好的,为什么突然要学「类」?
什么时候该用函数,什么时候必须上类?
这篇文章专治「面向对象恐惧症」。
一、先说结论(救命版)
如果你现在只想记住一句话:
函数是“做事”,类是“造物”。
场景 | 选函数 | 选类 |
|---|---|---|
做一个计算、转换、处理 | ✅ | ❌ |
只关心“结果是什么” | ✅ | ❌ |
数据 + 操作数据的逻辑要绑在一起 | ❌ | ✅ |
需要保存状态(记住之前发生过什么) | ❌ | ✅ |
同一套逻辑要反复“生产”多个对象 | ❌ | ✅ |
代码会被别人复用、维护 | ❌ | ✅ |
一句话判断法:
👉 如果代码里有明显的“名词”(学生、银行账号、游戏角色),优先考虑类;
👉 如果只有“动词”(计算、发送、解析),优先考虑函数。
二、从“函数思维”过渡到“类思维”
1️⃣ 只用函数的世界
假设我们要管理一个学生的成绩:
def calculate_average(scores): return sum(scores) / len(scores) def print_report(name, scores): avg = calculate_average(scores) print(f"{name} 的平均分是 {avg}") student_name = "张三" student_scores = [85, 90, 78] print_report(student_name, student_scores)问题来了:
student_name和student_scores是两个独立的变量函数并不“拥有”这些数据
很容易传错参数、漏传参数
当学生变多时,变量会爆炸式增长
👉函数是“游离的”,数据是“散落的”
2️⃣ 引入类:把数据和行为打包
同样的需求,用类来写:
class Student: def __init__(self, name, scores): self.name = name self.scores = scores def calculate_average(self): return sum(self.scores) / len(self.scores) def print_report(self): avg = self.calculate_average() print(f"{self.name} 的平均分是 {avg}") zhangsan = Student("张三", [85, 90, 78]) zhangsan.print_report()发生了什么变化?
name和scores被“装进”了Student这个容器里方法(
calculate_average、print_report)天然知道自己操作的是谁的数据不需要在函数之间传来传去
一个
Student就是一个“完整的学生概念”
👉类是“封装”
三、新手最困惑的三个概念(通俗版)
1️⃣ 什么是「对象」?
类 = 图纸
对象 = 房子
class Student: ... zhangsan = Student("张三", [85, 90, 78]) lisi = Student("李四", [70, 88, 92])Student:类(图纸)zhangsan、lisi:对象(实例 / 房子)
一个类可以造无数个对象。
2️⃣__init__是干什么的?
它是构造函数,也就是“造对象时的初始化动作”。
def __init__(self, name, scores): self.name = name self.scores = scores每次你写:
Student("张三", [85, 90, 78])Python 都会:
创建一个空对象
自动调用
__init__把数据挂到这个对象上
👉self就是“这个对象自己”
3️⃣self到底是个啥?
很多新手被self劝退,其实它很简单:
def print_report(self): print(self.name)等价于:
“在这个对象内部,访问这个对象的
name”
你可以把self理解为:
“我”
就像你说:“我要吃饭”,这个“我”就是self。
四、什么时候一定要用类?
✅ 情况 1:需要保存状态
函数做不到“记住事情”
class BankAccount: def __init__(self, owner, balance=0): self.owner = owner self.balance = balance def deposit(self, amount): self.balance += amount def withdraw(self, amount): if amount <= self.balance: self.balance -= amount else: print("余额不足") account = BankAccount("张三", 1000) account.deposit(500) account.withdraw(300) print(account.balance) # 1200如果用函数写,你需要不断传递balance,非常痛苦。
👉只要涉及“状态变化”,优先考虑类
✅ 情况 2:同一套逻辑要多次复用
比如写一个游戏:
class Player: def __init__(self, name, hp, attack): self.name = name self.hp = hp self.attack = attack def take_damage(self, damage): self.hp -= damage player1 = Player("战士", 100, 20) player2 = Player("法师", 80, 30)一个类,轻松生成 N 个玩家。
✅ 情况 3:逻辑越来越复杂,需要“分块”
当你的脚本变成这样:
def load_data(): ... def clean_data(): ... def train_model(): ... def evaluate_model(): ... def save_results(): ...这时候,函数已经太多、太散了。
用类可以把它们组织起来:
class ModelTrainer: def load_data(self): ... def clean_data(self): ... def train(self): ... def evaluate(self): ... def run(self): ...👉类是“代码的组织方式”
五、什么时候坚决不用类?
❌ 只是一次性脚本
def convert_excel_to_csv(input_file, output_file): ...这种脚本:
用完就丢
没有状态
不会被复用
强行写成类反而显得“装腔作势”。
❌ 只是简单计算
def add(a, b): return a + b你不会写成:
class Calculator: def add(self, a, b): return a + b这就叫过度设计。
六、一个决策流程图(背下来)
你要解决一个问题 │ ├─ 只是算个数 / 转个格式? │ └─ ✅ 用函数 │ ├─ 需要记住状态?(余额、血量、进度) │ └─ ✅ 用类 │ ├─ 有多个“名词”?(学生、账户、订单) │ └─ ✅ 用类 │ ├─ 函数超过 5~7 个,逻辑开始混乱? │ └─ ✅ 考虑用类 │ └─ 不确定? └─ ✅ 先用函数,等你觉得“乱了”再重构为类七、新手常见误区
❌ 误区 1:类一定比函数高级
错。
函数是基础,类是工具。
能用函数解决的问题,不要硬上类。
❌ 误区 2:所有东西都写成类
这是 Java 思维,不是 Python 思维。
Python 是多范式语言:支持函数式 + 面向对象。
Pythonic 的原则是:简单优于复杂
❌ 误区 3:self一定要写在所有函数第一个参数
只对实例方法成立。
静态方法、类方法是例外(但新手暂时不用管)。
八、实战对比:文件整理工具
函数版(适合一次性脚本)
def organize_by_type(folder): ... def batch_rename(folder): ... def clean_empty_folders(folder): ... organize_by_type("Downloads") batch_rename("Downloads")类版(适合做成工具库)
class FileOrganizer: def __init__(self, folder): self.folder = folder def organize_by_type(self): ... def batch_rename(self): ... def clean_empty_folders(self): ... def run_all(self): self.organize_by_type() self.batch_rename() self.clean_empty_folders() organizer = FileOrganizer("Downloads") organizer.run_all()👉类更适合“工具”“框架”“长期维护的项目”
九、学习路线建议
阶段 | 重点 |
|---|---|
第 1 周 | 熟练使用函数、参数、返回值 |
第 2 周 | 学会写类、 |
第 3 周 | 理解“状态”和“行为”的关系 |
第 4 周 | 学习继承、多态(不急,慢慢来) |
不要一上来就啃《面向对象思想》这种书,先写、先犯错、先重构。
十、总结一句话
函数是“动词”,类是“名词 + 动词”。
函数解决“怎么做”,类解决“谁来做 + 记住什么”。
当你发现自己在函数之间来回传递同一个变量时——
那就是类在向你招手了 🐍