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(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())
|
输出:
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))
|
__str__() 必须返回字符串,不要只在里面调用 print()。