类与对象详解
深入理解对象的创建与使用
类的结构
python
class ClassName:
"""类的文档字符串"""
# 类属性(所有对象共享)
class_variable = "shared"
def __init__(self, param1, param2):
"""构造函数"""
self.param1 = param1 # 实例属性
self.param2 = param2
def instance_method(self):
"""实例方法"""
return self.param1
@classmethod
def class_method(cls):
"""类方法"""
return cls.class_variable
@staticmethod
def static_method():
"""静态方法"""
return "不依赖类或实例"实例属性 vs 类属性
python
class Survey:
# 类属性(所有调查共享)
total_surveys = 0
def __init__(self, name, year):
# 实例属性(每个调查独有)
self.name = name
self.year = year
Survey.total_surveys += 1 # 修改类属性
survey1 = Survey("收入调查", 2024)
survey2 = Survey("健康调查", 2024)
print(survey1.name) # 收入调查(实例属性)
print(Survey.total_surveys) # 2(类属性)常用特殊方法
__init__:构造函数
python
class Respondent:
def __init__(self, id, age, income):
self.id = id
self.age = age
self.income = income
print(f"创建受访者 {id}")
resp = Respondent(1001, 30, 75000) # 自动调用 __init____str__:字符串表示
python
class Respondent:
def __init__(self, id, age):
self.id = id
self.age = age
def __str__(self):
return f"Respondent(ID={self.id}, Age={self.age})"
resp = Respondent(1001, 30)
print(resp) # Respondent(ID=1001, Age=30)__repr__:开发者表示
python
class Respondent:
def __init__(self, id, age):
self.id = id
self.age = age
def __repr__(self):
return f"Respondent({self.id}, {self.age})"
resp = Respondent(1001, 30)
print(repr(resp)) # Respondent(1001, 30)__len__:长度
python
class Survey:
def __init__(self, name):
self.name = name
self.responses = []
def add_response(self, response):
self.responses.append(response)
def __len__(self):
return len(self.responses)
survey = Survey("测试")
survey.add_response({'id': 1})
survey.add_response({'id': 2})
print(len(survey)) # 2实战案例
案例:学生管理系统
python
class Student:
"""学生类"""
school_name = "北京大学" # 类属性
def __init__(self, student_id, name, major, gpa=0.0):
self.student_id = student_id
self.name = name
self.major = major
self.gpa = gpa
self.courses = []
def enroll_course(self, course_name, credits):
"""选课"""
self.courses.append({
'name': course_name,
'credits': credits
})
def get_total_credits(self):
"""计算总学分"""
return sum(c['credits'] for c in self.courses)
def update_gpa(self, new_gpa):
"""更新 GPA"""
if 0 <= new_gpa <= 4.0:
self.gpa = new_gpa
else:
print("GPA 必须在 0-4.0 之间")
def __str__(self):
return f"{self.name} ({self.major}, GPA: {self.gpa})"
# 使用
alice = Student(2024001, "Alice Wang", "Economics", 3.8)
alice.enroll_course("Microeconomics", 4)
alice.enroll_course("Econometrics", 4)
print(alice)
print(f"总学分: {alice.get_total_credits()}")
print(f"学校: {Student.school_name}")案例:问卷数据容器
python
class SurveyData:
"""问卷数据管理类"""
def __init__(self, survey_name):
self.survey_name = survey_name
self.responses = []
def add_response(self, response):
"""添加响应"""
if self._validate(response):
self.responses.append(response)
return True
return False
def _validate(self, response):
"""私有方法:验证数据"""
required_fields = ['id', 'age', 'income']
return all(field in response for field in required_fields)
def get_average_income(self):
"""计算平均收入"""
if not self.responses:
return 0
incomes = [r['income'] for r in self.responses]
return sum(incomes) / len(incomes)
def filter_by_age(self, min_age, max_age):
"""按年龄筛选"""
return [r for r in self.responses
if min_age <= r['age'] <= max_age]
def __len__(self):
return len(self.responses)
def __str__(self):
return f"{self.survey_name}: {len(self)} responses"
# 使用
survey = SurveyData("2024收入调查")
survey.add_response({'id': 1, 'age': 30, 'income': 75000})
survey.add_response({'id': 2, 'age': 35, 'income': 85000})
print(survey)
print(f"平均收入: ${survey.get_average_income():,.0f}")
print(f"30-40岁: {len(survey.filter_by_age(30, 40))} 人")属性装饰器
@property:计算属性
python
class Respondent:
def __init__(self, income, tax_rate=0.25):
self.income = income
self.tax_rate = tax_rate
@property
def net_income(self):
"""作为属性访问,而不是方法"""
return self.income * (1 - self.tax_rate)
@property
def tax_amount(self):
return self.income * self.tax_rate
resp = Respondent(100000, 0.3)
print(resp.net_income) # 70000(像属性一样访问)
print(resp.tax_amount) # 30000
# 不需要 resp.net_income()封装:公有 vs 私有
python
class BankAccount:
def __init__(self, balance):
self.balance = balance # 公有属性
self._transactions = [] # 约定私有(单下划线)
self.__pin = "1234" # 真正私有(双下划线)
def deposit(self, amount):
"""公有方法"""
self.balance += amount
self._log_transaction("deposit", amount)
def _log_transaction(self, type, amount):
"""私有方法(约定)"""
self._transactions.append({
'type': type,
'amount': amount
})
account = BankAccount(1000)
account.deposit(500)
print(account.balance) # 1500(可访问)
print(account._transactions) # 可访问但不推荐
# print(account.__pin) # AttributeError练习题
练习 1:创建完整的类
python
# 创建 Course 类
# 属性: course_code, name, instructor, max_students, enrolled
# 方法:
# - add_student(student_name): 添加学生(检查人数限制)
# - drop_student(student_name): 移除学生
# - is_full(): 是否已满
# - get_enrollment_rate(): 返回选课率练习 2:实现特殊方法
python
# 为 Survey 类实现:
# - __str__: 返回 "Survey: {name} ({count} responses)"
# - __len__: 返回响应数量
# - __getitem__: 支持 survey[0] 访问第 i 个响应下一步
在下一节中,我们将了解 OOP 在数据科学中的应用。
继续!