面向对象编程入门
理解
df.method()的秘密 —— 为什么数据科学需要 OOP
什么是面向对象编程(OOP)?
面向对象编程(Object-Oriented Programming, OOP) 是一种编程范式,将数据和操作数据的方法组织在一起。
为什么社科学生要学 OOP?
你已经在用 OOP 了!
python
import pandas as pd
df = pd.DataFrame({'age': [25, 30, 35]})
result = df.mean() # df 是对象,mean() 是方法核心概念:
- 对象(Object):数据 + 方法的集合
- 类(Class):对象的模板/蓝图
- 方法(Method):对象的函数
为什么需要 OOP?
场景:管理受访者信息
传统方式(字典):
python
respondent1 = {
'id': 1001,
'name': 'Alice',
'age': 30,
'income': 75000
}
# 计算税后收入(函数分离)
def calculate_net_income(respondent, tax_rate=0.25):
return respondent['income'] * (1 - tax_rate)
net = calculate_net_income(respondent1)OOP 方式(类):
python
class Respondent:
def __init__(self, id, name, age, income):
self.id = id
self.name = name
self.age = age
self.income = income
def calculate_net_income(self, tax_rate=0.25):
"""数据和方法在一起"""
return self.income * (1 - tax_rate)
# 使用
resp1 = Respondent(1001, 'Alice', 30, 75000)
net = resp1.calculate_net_income() # 更直观!优势:
- 数据和方法绑定在一起
- 代码更有组织性
- 便于复用和维护
理解 Pandas 的 OOP
python
import pandas as pd
# DataFrame 是一个类
df = pd.DataFrame({'x': [1, 2, 3]}) # df 是 DataFrame 的实例(对象)
# 以下都是方法(对象的函数)
df.head() # 查看前几行
df.describe() # 描述性统计
df.mean() # 平均值
df.to_csv('out.csv') # 保存
# 以下是属性(对象的数据)
df.shape # (3, 1)
df.columns # Index(['x'])
df.dtypes # 数据类型对比 R:
r
# R (更函数式)
df <- data.frame(x = c(1, 2, 3))
head(df) # 函数调用
mean(df$x) # 函数调用
write.csv(df, 'out.csv')python
# Python (更面向对象)
df = pd.DataFrame({'x': [1, 2, 3]})
df.head() # 方法调用
df['x'].mean() # 方法调用
df.to_csv('out.csv')实战:创建简单的类
示例 1:学生类
python
class Student:
"""学生类"""
def __init__(self, name, age, major):
"""构造函数:创建对象时自动调用"""
self.name = name
self.age = age
self.major = major
self.courses = []
def enroll(self, course):
"""添加课程"""
self.courses.append(course)
print(f"{self.name} 已注册 {course}")
def display_info(self):
"""显示信息"""
print(f"姓名: {self.name}")
print(f"年龄: {self.age}")
print(f"专业: {self.major}")
print(f"课程: {', '.join(self.courses)}")
# 使用
alice = Student("Alice", 25, "Economics")
alice.enroll("Microeconomics")
alice.enroll("Econometrics")
alice.display_info()示例 2:调查响应类
python
class SurveyResponse:
"""问卷响应类"""
def __init__(self, respondent_id, age, gender, income):
self.respondent_id = respondent_id
self.age = age
self.gender = gender
self.income = income
def is_valid(self):
"""验证数据"""
return (
18 <= self.age <= 100 and
self.income >= 0 and
self.gender in ['Male', 'Female', 'Other']
)
def income_category(self):
"""收入分类"""
if self.income < 50000:
return "低收入"
elif self.income < 100000:
return "中收入"
else:
return "高收入"
def summary(self):
"""生成摘要"""
return f"ID{self.respondent_id}: {self.gender}, {self.age}岁, {self.income_category()}"
# 使用
resp1 = SurveyResponse(1001, 30, 'Female', 75000)
print(resp1.is_valid()) # True
print(resp1.income_category()) # 中收入
print(resp1.summary()) # ID1001: Female, 30岁, 中收入OOP 核心概念
1. 类与对象
python
# 类是模板
class Dog:
def bark(self):
return "Woof!"
# 对象是实例
dog1 = Dog() # 创建对象
dog2 = Dog() # 创建另一个对象
print(dog1.bark()) # Woof!
print(dog2.bark()) # Woof!2. 属性与方法
python
class Respondent:
def __init__(self, age, income):
# 属性(数据)
self.age = age
self.income = income
# 方法(函数)
def is_high_earner(self):
return self.income > 100000
resp = Respondent(30, 120000)
print(resp.age) # 属性访问
print(resp.is_high_earner()) # 方法调用3. self 参数
python
class Person:
def __init__(self, name):
self.name = name # self 指向当前对象
def greet(self):
# self 让方法访问对象的属性
return f"Hello, I'm {self.name}"
p1 = Person("Alice")
p2 = Person("Bob")
print(p1.greet()) # Hello, I'm Alice
print(p2.greet()) # Hello, I'm Bob面向对象 vs 函数式
函数式风格
python
def create_respondent(id, age, income):
return {'id': id, 'age': age, 'income': income}
def calculate_tax(respondent, rate):
return respondent['income'] * rate
def is_valid(respondent):
return respondent['age'] >= 18
resp = create_respondent(1001, 30, 75000)
tax = calculate_tax(resp, 0.25)
valid = is_valid(resp)面向对象风格
python
class Respondent:
def __init__(self, id, age, income):
self.id = id
self.age = age
self.income = income
def calculate_tax(self, rate=0.25):
return self.income * rate
def is_valid(self):
return self.age >= 18
resp = Respondent(1001, 30, 75000)
tax = resp.calculate_tax()
valid = resp.is_valid()何时用哪种?
- 函数式:简单脚本、数据分析
- OOP:大型项目、需要复用的组件
社科学生的 OOP
你不需要深入学习 OOP,但要理解:
- Pandas DataFrame 是对象
python
df.head() # 调用方法
df.shape # 访问属性- Scikit-learn 模型是对象
python
from sklearn.linear_model import LinearRegression
model = LinearRegression() # 创建对象
model.fit(X, y) # 调用方法
predictions = model.predict(X_test)- Statsmodels 也用 OOP
python
import statsmodels.formula.api as smf
model = smf.ols('income ~ education + age', data=df)
results = model.fit()
print(results.summary())练习题
练习 1:创建课程类
python
# 创建 Course 类
# 属性: name, credits, students (列表)
# 方法:
# - add_student(student_name)
# - get_enrollment() # 返回学生数
# - display_roster() # 显示所有学生
course = Course("Econometrics", 4)
course.add_student("Alice")
course.add_student("Bob")
print(course.get_enrollment()) # 2
course.display_roster()练习 2:改写为类
python
# 将以下函数式代码改为 OOP 风格
def create_survey(name, year):
return {'name': name, 'year': year, 'responses': []}
def add_response(survey, response):
survey['responses'].append(response)
def get_response_count(survey):
return len(survey['responses'])
# 改写为 Survey 类下一步
在下一节中,我们将学习 类与对象的详细用法。
继续!