Skip to main content

类与面向对象

面向对象编程(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
  • 实例和属性用小写+下划线
  • 每个类前面配文档字符串
  • 类之间用两个空行分隔,方法之间用一个空行