Module 6: 面向对象编程基础 (OOP)
理解
df.method()的秘密 —— 为什么数据科学需要 OOP
本章概览
如果你用过 Pandas,你已经在使用面向对象编程(OOP)了!每次调用 df.head()、df.mean()、model.fit(X, y),你都在与对象交互。本章将揭开 OOP 的神秘面纱,帮助你理解数据科学库的设计哲学,并学会创建自己的类。
重要提示:社科学生不需要深入学习 OOP,但要理解其基本概念,这样才能更好地使用 Pandas、Scikit-learn 等库。
学习目标
学完本章后,你将能够:
- 理解类(Class)与对象(Object)的概念
- 知道为什么 Pandas、Scikit-learn 使用 OOP
- 理解
df.method()和df.attribute的含义 - 创建简单的类来组织代码
- 使用特殊方法(
__init__、__str__、__len__) - 对比面向对象 vs 函数式编程
- 构建数据分析流水线类
章节内容
01 - 面向对象编程入门
核心问题: 为什么社科学生要学 OOP?
核心内容:
- 你已经在用 OOP 了:python
df = pd.DataFrame({'age': [25, 30, 35]}) result = df.mean() # df 是对象,mean() 是方法 - OOP 核心概念:
- 对象(Object):数据 + 方法的集合
- 类(Class):对象的模板/蓝图
- 方法(Method):对象的函数
- 属性(Attribute):对象的数据
- 为什么需要 OOP:数据和方法绑定在一起,代码更有组织性
- 理解 Pandas 的 OOP 设计:python
df.head() # 方法调用 df.shape # 属性访问 df.to_csv() # 方法调用 - 对比 Python(面向对象) vs R(函数式):
- Python:
df.mean() - R:
mean(df$x)
- Python:
- 创建第一个类:学生类、调查响应类
- 面向对象 vs 函数式编程的选择
为什么重要?
- 理解 Pandas、Scikit-learn 的使用方式
- 知道何时用类、何时用函数
- 让代码更易维护和复用
实际应用:
class SurveyResponse:
def __init__(self, id, age, income):
self.id = id
self.age = age
self.income = income
def is_valid(self):
return 18 <= self.age <= 100 and self.income >= 0
def income_category(self):
if self.income < 50000:
return "低收入"
elif self.income < 100000:
return "中收入"
else:
return "高收入"
resp = SurveyResponse(1001, 30, 75000)
print(resp.is_valid()) # True
print(resp.income_category()) # 中收入02 - 类与对象详解
核心问题: 如何创建和使用类?
核心内容:
- 类的完整结构:python
class ClassName: class_variable = "共享数据" # 类属性 def __init__(self, param): self.param = param # 实例属性 def method(self): # 实例方法 return self.param - 实例属性 vs 类属性:
- 实例属性:每个对象独有(
self.name) - 类属性:所有对象共享(
ClassName.variable)
- 实例属性:每个对象独有(
- 常用特殊方法(魔法方法):
__init__:构造函数(创建对象时调用)__str__:字符串表示(用于print())__repr__:开发者表示(用于调试)__len__:长度(用于len())
- @property 装饰器:将方法转为属性python
@property def net_income(self): return self.income * 0.75 # 使用:resp.net_income(无需括号) - 封装:公有 vs 私有:
- 公有:
self.balance - 约定私有:
self._transactions(单下划线) - 真正私有:
self.__pin(双下划线)
- 公有:
实战案例:
class Student:
school_name = "北京大学" # 类属性
def __init__(self, id, name, major, gpa=0.0):
self.id = id
self.name = name
self.major = major
self.gpa = gpa
self.courses = []
def enroll_course(self, name, credits):
self.courses.append({'name': name, 'credits': credits})
def get_total_credits(self):
return sum(c['credits'] for c in self.courses)
def __str__(self):
return f"{self.name} ({self.major}, GPA: {self.gpa})"
alice = Student(2024001, "Alice", "Economics", 3.8)
alice.enroll_course("Microeconomics", 4)
print(alice) # Alice (Economics, GPA: 3.8)03 - OOP 在数据科学中的应用
核心问题: 为什么数据科学库都使用 OOP?
核心内容:
- Pandas 的 OOP 设计:
- DataFrame 和 Series 都是对象
- 链式调用的优势:python
result = (df .query('age > 30') .assign(log_income=lambda x: np.log(x['income'])) .sort_values('income') .reset_index(drop=True) )
- Scikit-learn 的 OOP 设计:
- 统一的 API:
fit()→predict()
pythonmodel = LinearRegression() model.fit(X, y) predictions = model.predict(X_test) print(model.coef_, model.intercept_) # 访问属性 - 统一的 API:
- Statsmodels 的 OOP 设计:python
model = smf.ols('income ~ education + age', data=df) results = model.fit() print(results.summary(), results.rsquared) - 创建自己的数据科学类:
- 简单线性回归类(教学用)
- 数据处理流水线类
- OOP 最佳实践:
- 设计可链式调用的方法(返回
self) - 使用属性存储元数据(
is_fitted,n_features) - 实现
__repr__便于调试
- 设计可链式调用的方法(返回
实战案例:数据流水线类:
class DataPipeline:
def __init__(self, df):
self.df = df.copy()
self.steps = []
def remove_missing(self):
self.df = self.df.dropna()
self.steps.append("remove_missing")
return self # 支持链式调用
def filter_age(self, min_age, max_age):
self.df = self.df[(self.df['age'] >= min_age) &
(self.df['age'] <= max_age)]
self.steps.append(f"filter_age({min_age}, {max_age})")
return self
def get_result(self):
return self.df
# 链式调用
result = (DataPipeline(df)
.remove_missing()
.filter_age(18, 65)
.get_result()
)面向对象 vs 函数式编程
| 维度 | 函数式编程 | 面向对象编程 |
|---|---|---|
| 组织方式 | 函数 + 数据分离 | 数据和方法绑定 |
| 典型语言 | R, MATLAB | Python, Java |
| 适用场景 | 简单脚本、数据分析 | 大型项目、库开发 |
| 代码风格 | mean(df$x) | df['x'].mean() |
函数式风格(R 风格)
# 数据和函数分离
def calculate_tax(income, rate):
return income * rate
def is_valid(age):
return age >= 18
income = 75000
tax = calculate_tax(income, 0.25)面向对象风格(Python 风格)
# 数据和方法绑定
class Respondent:
def __init__(self, income, age):
self.income = income
self.age = age
def calculate_tax(self, rate=0.25):
return self.income * rate
def is_valid(self):
return self.age >= 18
resp = Respondent(75000, 30)
tax = resp.calculate_tax()如何学习本章?
学习路线
第 1 天(2小时): OOP 入门
- 阅读 01 - 面向对象编程入门
- 理解类、对象、方法、属性的概念
- 创建第一个类(Student 或 SurveyResponse)
第 2 天(3小时): 类与对象详解
- 阅读 02 - 类与对象详解
- 学习特殊方法(
__init__、__str__、__len__) - 实践 @property 装饰器
第 3 天(2小时): 数据科学中的 OOP
- 阅读 03 - OOP 在数据科学中的应用
- 理解 Pandas、Scikit-learn 的 OOP 设计
- 创建简单的数据流水线类
总时间: 7 小时(1 周)
最小化学习路径
对于社科学生,OOP 不是核心技能,优先级如下:
必学(理解别人的代码,4小时):
- 01 - OOP 入门(理解 Pandas 的 OOP 设计)
- 03 - 数据科学应用(理解 Scikit-learn 的使用)
- 知道
df.method()和df.attribute的区别
选学(自己写类,3小时):
- 02 - 类与对象详解
- 特殊方法、@property
- 创建自己的类
可跳过(高级主题):
- 类方法、静态方法
- 继承、多态
- 复杂的封装设计
学习建议
理解优先于创建
- 先理解 Pandas、Scikit-learn 的 OOP 用法
- 再考虑是否需要自己创建类
- 大多数数据分析用函数就够了
从使用到创建
python# 第一步:会用别人的类 df = pd.DataFrame({'x': [1, 2, 3]}) df.mean() # 第二步:理解原理 # DataFrame 是类,df 是对象,mean() 是方法 # 第三步:创建自己的类(可选) class MyDataFrame: def __init__(self, data): self.data = data何时需要创建类?
- 需要封装复杂的数据 + 操作
- 需要复用的组件(数据流水线、自定义模型)
- 大型项目需要组织代码
- 简单脚本、一次性分析(用函数)
对比学习
- Python 的 OOP 风格:数据和方法绑定
- R 的函数式风格:数据和函数分离
- Stata:几乎不用 OOP(全是命令)
常见问题
Q: 我必须学 OOP 吗?能不能跳过? A: 不能完全跳过。你不需要深入学习,但要理解基本概念,否则无法理解 Pandas、Scikit-learn 的文档。建议:理解 df.method() 的含义即可,不必自己写复杂的类。
Q: 为什么 Python 用 OOP,R 用函数式? A:
- Python 是通用编程语言,OOP 更适合大型项目
- R 是统计语言,函数式更符合数学习惯
- 两者都能完成数据分析,只是风格不同
Q: df.head() 和 head(df) 有什么区别? A:
df.head():OOP 风格,DataFrame 对象调用自己的方法head(df):函数式风格,函数接受 DataFrame 作为参数- Python 偏好前者,R 偏好后者
Q: 什么是 self? A: self 代表对象自己。当你调用 resp.is_valid() 时,Python 自动将 resp 传给 self,这样方法就能访问对象的属性。
Q: 我什么时候需要自己创建类? A:
- 需要:构建可复用的数据流水线、封装复杂分析逻辑、大型项目
- 不需要:简单脚本、一次性分析、探索性数据分析
Q: OOP 会让代码更快吗? A: 不会。OOP 的优势在于组织性和可维护性,而非性能。对于数据分析,性能主要取决于算法和库(NumPy、Pandas),而非 OOP。
下一步
完成本章后,你将掌握:
- OOP 的基本概念(类、对象、方法、属性)
- 理解 Pandas、Scikit-learn 的 OOP 设计
- 知道何时用类、何时用函数
- 能创建简单的类来组织代码
在 Module 7 中,我们将学习文件 I/O,学会读写 CSV、Excel、JSON、Stata 等数据文件。
在 Module 9 中,我们将深入学习 NumPy、Pandas、Matplotlib 等数据科学核心库。
OOP 不是社科学生的核心技能,理解即可!继续前进!