类与面向对象
面向对象编程(OOP)是一种组织代码的方式。把数据和操作数据的方法封装在一起,形成一个"类",然后根据类创建具体的"实例"。
创建类
用 class 关键字定义类:
class Student:
"""表示一个学生"""
def __init__(self, name, major):
"""初始化学生属性"""
self.name = name
self.major = major
self.scores = []
def add_score(self, score):
"""添加成绩"""
self.scores.append(score)
def get_average(self):
"""计算平均分"""
if not self.scores:
return 0
return sum(self.scores) / len(self.scores)
init 方法
__init__ 是类的构造函数,创建实例时自动调用。self 指向实例本身,必须通过它访问实例的属性。
创建实例
alice = Student("Alice", "CS")
print(alice.name) # Alice
print(alice.major) # CS
alice.add_score(85)
alice.add_score(92)
print(alice.get_average()) # 88.5
每个实例有自己独立的数据:
bob = Student("Bob", "AI")
bob.add_score(78)
print(alice.scores) # [85, 92]
print(bob.scores) # [78]
修改属性
可以直接访问属性修改:
alice.major = "AI"
也可以通过方法修改(推荐,可以在方法里加校验逻辑):
class Student:
# ...
def change_major(self, new_major):
valid_majors = ["CS", "AI", "DS", "SE"]
if new_major in valid_majors:
self.major = new_major
else:
print(f"不支持的专业: {new_major}")
继承
继承让子类获得父类的所有属性和方法,还可以添加自己特有的功能。
class Member(Student):
"""社团成员,继承自 Student"""
def __init__(self, name, major, role):
"""初始化父类属性,再添加自己的属性"""
super().__init__(name, major)
self.role = role
self.projects = []
def join_project(self, project_name):
"""加入项目"""
self.projects.append(project_name)
def show_info(self):
"""显示成员信息"""
print(f"{self.name} ({self.major})")
print(f" 角色: {self.role}")
print(f" 参与项目: {', '.join(self.projects)}")
carol = Member("Carol", "DS", "算法组长")
carol.join_project("图像识别")
carol.join_project("聊天机器人")
carol.show_info()
重写父类方法
子类可以覆盖父类的方法:
class Member(Student):
# ...
def get_average(self):
"""社团成员平均分计算方式不同:去掉最低分"""
if len(self.scores) <= 1:
return super().get_average()
sorted_scores = sorted(self.scores)
return sum(sorted_scores[1:]) / len(sorted_scores[1:])
把实例用作属性
当类的属性太多时,可以把相关属性拆成另一个类:
class ProjectHistory:
"""项目经历"""
def __init__(self):
self.projects = []
def add(self, name, role):
self.projects.append({"name": name, "role": role})
def list_all(self):
for p in self.projects:
print(f" - {p['name']} ({p['role']})")
class Member(Student):
def __init__(self, name, major, role):
super().__init__(name, major)
self.role = role
self.history = ProjectHistory() # 实例作为属性
def join_project(self, name):
self.history.add(name, self.role)
导入类
把类写在单独的文件里,方便复用:
# models.py
class Student:
# ...
class Member(Student):
# ...
# main.py
from models import Member
alice = Member("Alice", "CS", "前端")
也可以导入整个模块:
import models
alice = models.Member("Alice", "CS", "前端")
或者从模块导入多个类:
from models import Student, Member
类的编码风格
- 类名用大驼峰:
StudentInfo而不是student_info - 实例和属性用小写+下划线
- 每个类前面配文档字符串
- 类之间用两个空行分隔,方法之间用一个空行