Python 函数和类到底怎么选?新手彻底搞懂「面向对象」

Python 函数和类到底怎么选?新手彻底搞懂「面向对象」

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_namestudent_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()

发生了什么变化?

  • namescores被“装进”了Student这个容器里

  • 方法(calculate_averageprint_report)天然知道自己操作的是谁的数据

  • 不需要在函数之间传来传去

  • 一个Student就是一个“完整的学生概念”

👉类是“封装”


三、新手最困惑的三个概念(通俗版)

1️⃣ 什么是「对象」?

类 = 图纸

对象 = 房子

class Student: ... zhangsan = Student("张三", [85, 90, 78]) lisi = Student("李四", [70, 88, 92])
  • Student:类(图纸)

  • zhangsanlisi:对象(实例 / 房子)

一个类可以造无数个对象。


2️⃣__init__是干什么的?

它是构造函数,也就是“造对象时的初始化动作”。

def __init__(self, name, scores): self.name = name self.scores = scores

每次你写:

Student("张三", [85, 90, 78])

Python 都会:

  1. 创建一个空对象

  2. 自动调用__init__

  3. 把数据挂到这个对象上

👉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 周

学会写类、__init__self

第 3 周

理解“状态”和“行为”的关系

第 4 周

学习继承、多态(不急,慢慢来)

不要一上来就啃《面向对象思想》这种书,先写、先犯错、先重构。


十、总结一句话

函数是“动词”,类是“名词 + 动词”。

函数解决“怎么做”,类解决“谁来做 + 记住什么”。

当你发现自己在函数之间来回传递同一个变量时——

那就是类在向你招手了 🐍