面向对象编程(OOP)基础

Python 面向对象编程(OOP)基础

1. 什么是面向对象?

面向对象把相关的数据和操作放在一起,用“对象”描述事物。

例如,一个学生对象可以包含:

  • 属性:姓名、成绩。
  • 方法:自我介绍、修改成绩。
概念 含义 示例
类(class) 定义对象的结构和行为 Student
对象(实例) 根据类创建的具体个体 Student("小明", 90)
属性 对象保存的数据 student.name
方法 对象提供的操作 student.introduce()

2. 定义类与创建对象

1
2
3
4
5
6
7
8
9
10
11
class Student:
def __init__(self, name, score):
self.name = name
self.score = score

def introduce(self):
print(f"我叫{self.name},成绩是{self.score}分")


student = Student("小明", 90)
student.introduce()

记住三个要点:

  • class 用来定义类,类名通常采用 StudentManager 这样的命名方式。
  • Student(...) 创建实例。
  • __init__() 在实例创建后自动执行,用来初始化属性,不能返回非 None 的值。

3. 理解 self

self 表示当前调用方法的实例。

1
student.introduce()

可以理解为:

1
Student.introduce(student)

定义实例方法时,通常把 self 写在第一个参数位置;通过实例调用时,Python 自动传入它。

1
2
def change_score(self, new_score):
self.score = new_score

self.score 是对象的属性,new_score 是这次调用传入的参数。

4. 访问与修改属性

1
2
print(student.name)    # 读取属性
student.score = 95 # 修改属性

如果修改时需要检查规则,可以使用方法:

1
2
3
4
5
6
7
8
9
class Student:
def __init__(self, name, score):
self.name = name
self.set_score(score)

def set_score(self, score):
if not 0 <= score <= 100:
raise ValueError("成绩必须在0~100之间")
self.score = score

注意:这个检查只在调用 set_score() 时执行,直接写 student.score = 200 仍然会绕过它。

5. 实例属性与类属性

类型 定义位置 适合保存
实例属性 通常在 __init__() 中通过 self 定义 每个对象自己的数据
类属性 类内部、方法外部 多个对象共用的信息
1
2
3
4
5
class Student:
school = "第一中学" # 类属性

def __init__(self, name):
self.name = name # 实例属性
1
2
3
4
5
6
a = Student("小明")
b = Student("小红")

print(a.name) # 小明
print(b.name) # 小红
print(Student.school) # 第一中学

易错点:不要把每个实例独有的列表、字典写成类属性。

1
2
3
class Classroom:
def __init__(self):
self.students = [] # 每个实例拥有独立的列表

6. 封装与属性命名

封装就是把相关数据和操作组织在类中,通过合适的方法使用它们。

写法 含义
name 普通属性
_name 约定为内部使用,外部仍可以访问
__name 触发名称改写,主要用于减少继承中的命名冲突

Python 的双下划线属性不是绝对无法访问的“私有属性”。

需要控制属性的读取和修改时,可以使用 @property:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Student:
def __init__(self, score):
self.score = score

@property
def score(self):
return self._score

@score.setter
def score(self, value):
if not 0 <= value <= 100:
raise ValueError("成绩必须在0~100之间")
self._score = value

使用时仍然像普通属性:

1
2
3
student = Student(90)
student.score = 95 # 自动执行检查
print(student.score)

这里用 _score 保存实际数据,避免在 setter 中反复调用自身。

7. 继承与 super()

继承让子类复用父类的属性和方法。

1
2
3
4
5
6
7
8
9
10
11
12
class Person:
def __init__(self, name):
self.name = name

def introduce(self):
print(f"我叫{self.name}")


class Student(Person):
def __init__(self, name, score):
super().__init__(name)
self.score = score
1
2
student = Student("小明", 90)
student.introduce() # 使用继承的方法
  • class Student(Person):Student 继承 Person。
  • 在这个单继承例子中,super().__init__(name) 调用父类的初始化方法。
  • 子类如果自己定义了 __init__(),父类的初始化方法不会自动再执行一次,需要按需调用。

8. 方法重写与多态

方法重写:子类定义与父类同名的方法,提供自己的行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Animal:
def speak(self):
return "动物发出声音"


class Cat(Animal):
def speak(self):
return "喵喵"


class Dog(Animal):
def speak(self):
return "汪汪"

多态:使用同样的调用方式,不同对象表现出不同的行为。

1
2
for animal in [Cat(), Dog()]:
print(animal.speak())

输出:

1
2
喵喵
汪汪

Python 中,只要对象提供了所需的方法,就可以这样使用;不一定必须继承同一个父类。

9. 三种方法

类型 写法 自动传入 常见用途
实例方法 普通 def 实例 self 读取、修改实例数据
类方法 @classmethod 类 cls 根据其他形式的数据创建实例
静态方法 @staticmethod 无 与类相关,但不需要实例或类数据的工具操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Student:
def __init__(self, name):
self.name = name

def introduce(self):
return f"我叫{self.name}"

@classmethod
def from_text(cls, text):
return cls(text.strip())

@staticmethod
def is_valid_score(score):
return 0 <= score <= 100
1
2
3
student = Student.from_text(" 小明 ")
print(student.introduce())
print(Student.is_valid_score(90))

10. 常用特殊方法

特殊方法也叫“魔术方法”,名称前后都有双下划线。

方法 作用 触发方式
__init__ 初始化实例 Student(...)
__str__ 提供便于阅读的字符串 str(obj)、print(obj)
__repr__ 提供便于调试的字符串 repr(obj)、容器展示
__len__ 定义长度 len(obj)
1
2
3
4
5
6
7
class Student:
def __init__(self, name, score):
self.name = name
self.score = score

def __str__(self):
return f"{self.name}:{self.score}分"
1
print(Student("小明", 90))  # 小明:90分

__str__() 必须返回字符串,不要只在里面调用 print()。


面向对象编程(OOP)基础
https://umeshu.cn/2021/05/02/Python/面向对象编程(OOP)基础/
作者
IchiharaYuuko
发布于
2021年5月2日
许可协议