Python 是一种多范式语言,支持函数式、过程式和面向对象编程(OOP)。OOP 提供了组织代码、增强可重用性、提高可维护性的强大手段。
Python 的 OOP 主要包括以下核心特性:
- 封装(Encapsulation)
- 继承(Inheritance)
- 多态(Polymorphism)
- 抽象(Abstraction)
- 类方法与静态方法(Class & Static Methods)
- 多重继承与方法解析顺序(MRO)
8.1 类和对象
**类(Class)**是创建对象的模板,**对象(Object)**是类的具体实例。
class Dog:
def bark(self):
print("汪汪!")
my_dog = Dog()
my_dog.bark() # 输出:汪汪!
8.2 属性和方法
属性和方法是类的两个核心成员:属性用于描述对象的状态,方法用于定义对象的行为。
一、属性
1️⃣ 实例属性
定义在 __init__() 中,通过 self.属性名 创建,属于每个对象自身。
class Student:
def __init__(self, name):
self.name = name
2️⃣ 类属性
直接定义在类体中,所有实例共享一份,通常用于记录公共数据。
class Student:
school = "华夏学校" # 类属性
def __init__(self, name):
self.name = name
✅ 属性对比小结表
|
属性类型 |
定义方式 |
归属 |
是否共享 |
|
实例属性 |
self.name |
每个对象 |
否 |
|
类属性 |
类名.属性名 |
所有对象共享 |
是 |
二、方法
方法是定义在类中的函数,用于描述对象的行为,绑定对象或类进行调用。
1️⃣ 实例方法
- 定义方式:在类中使用 def 定义,参数中必须有 self;
- self 表示当前对象;
- 可以访问和修改对象的实例属性。
class Dog:
def __init__(self, name):
self.name = name
def bark(self): # 实例方法
print(f"{self.name} 汪汪叫")
2️⃣ 类方法(详见 8.8)
- 使用 @classmethod 装饰;
- 第一个参数是 cls,表示类;
- 可操作类属性,适合构建工厂方法等。
3️⃣ 静态方法(详见 8.8)
- 使用 @staticmethod 装饰;
- 无 self 或 cls;
- 像普通函数,但在类中定义,与类逻辑相关联。
三、方法与函数的区别
|
区别点 |
函数 |
方法 |
|
定义位置 |
类外 |
类内 |
|
是否绑定 |
无绑定 |
绑定类或对象 |
|
第一个参数 |
无(可选) |
self / cls 等必须 |
|
调用方式 |
函数名() |
对象.方法名() 或 类.方法名() |
✅ 方法调用示例汇总
class Calculator:
def add(self, a, b): # 实例方法
return a + b
@classmethod
def info(cls): # 类方法
print("这是一个计算器类")
@staticmethod
def help(): # 静态方法
print("请输入两个数字进行加法")
调用方式:
calc = Calculator()
print(calc.add(2, 3)) # 实例方法
Calculator.info() # 类方法
Calculator.help() # 静态方法
8.3 构造函数与析构函数
- 构造函数 __init__():对象创建后自动调用,用于初始化;
- 析构函数 __del__():对象销毁前调用,用于资源释放(慎用)。
class FileHandler:
def __init__(self, filename):
self.filename = filename
print(f"打开文件:{self.filename}")
def __del__(self):
print(f"关闭文件:{self.filename}")
⚠ 注意:Python 的垃圾回收机制不保证 __del__() 的及时性,资源释放建议使用 with 语句更安全。
8.4 继承
子类可以继承父类的属性和方法,实现代码复用。
class Animal:
def eat(self):
print("吃东西")
class Dog(Animal):
def bark(self):
print("汪汪")
d = Dog()
d.eat()
d.bark()
8.5 方法重写(Override)
子类可以重写父类的方法,提供新的实现。
class Animal:
def speak(self):
print("动物叫")
class Cat(Animal):
def speak(self):
print("喵喵")
c = Cat()
c.speak() # 输出:喵喵
8.6 多态(含鸭子类型)
多态指同一个接口,作用于不同对象时,表现出不同的行为。
🦆 鸭子类型
Python 不依赖类型声明,而采用“鸭子类型”:
“如果一个对象走路像鸭子、叫声像鸭子,那它就是鸭子。”
即:只要对象有某个方法,不关心其类型和继承关系,就可以调用。
示例 1:基于继承的多态
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪")
class Cat(Animal):
def speak(self):
print("喵喵")
def make_sound(animal):
animal.speak()
示例 2:鸭子类型实现的多态(无继承)
class Duck:
def speak(self):
print("嘎嘎")
class Person:
def speak(self):
print("人在模仿鸭子:嘎嘎")
def make_sound(thing):
thing.speak()
8.7 封装与私有属性
封装是面向对象编程的重要特性,指的是将对象的属性和方法包装在一起,隐藏对象的内部细节,只暴露必要的接口。这样可以防止外部代码随意访问和修改对象的内部状态,提高代码的安全性和健壮性。
1.私有属性的定义
在 Python 中,私有属性(Private Attribute)是指不希望被类外部直接访问的属性。虽然 Python 并没有像某些语言(如 Java、C++)那样严格的访问控制,但通过命名规范,约定私有属性的访问限制。
- 使用双下划线开头(__)来定义私有属性,比如:
class Person:
def __init__(self, name, age):
self.name = name # 公共实例属性
self.__age = age # 私有属性
- 这种写法触发了名称重整(Name Mangling)机制,Python 会将属性名 __age 自动改为 _Person__age,使其不易被外部直接访问。
2.私有属性的作用
- 防止外部随意修改,保护对象内部数据;
- 让类可以控制属性的访问和修改方式,一般配合 getter 和 setter 使用。
3.访问私有属性
虽然不能直接用 obj.__age 访问,但可以通过类内部方法访问:
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def get_age(self):
return self.__age
p = Person("小明", 18)
print(p.get_age()) # 18
通过特殊名称访问(不建议,绕过封装):
print(p._Person__age) # 18
4.私有属性 vs 实例属性 vs 类属性
|
属性类型 |
定义方式 |
访问权限 |
作用范围 |
共享情况 |
备注 |
|
实例属性 |
self.属性名 |
公共,可直接访问 |
绑定到对象实例 |
每个实例独立 |
通常代表对象的状态 |
|
类属性 |
在类体中定义 |
公共,可直接访问 |
绑定到类 |
所有实例共享 |
用于所有实例共享的数据 |
|
私有属性 |
__属性名(双下划线开头) |
受限,类外部不易访问 |
绑定到对象实例 |
每个实例独立 |
通过名称重整机制隐藏,实现封装 |
示例演示
class Example:
class_attr = "类属性"
def __init__(self, value):
self.instance_attr = value # 实例属性
self.__private_attr = "私有属性" # 私有属性
obj = Example(123)
# 访问实例属性
print(obj.instance_attr) # 123
# 访问类属性
print(obj.class_attr) # 类属性
print(Example.class_attr) # 类属性
# 访问私有属性(直接访问会报错)
# print(obj.__private_attr) # AttributeError
# 通过名称重整访问私有属性(不推荐)
print(obj._Example__private_attr) # 私有属性
5.封装的意义
- 通过私有属性,实现数据隐藏,防止外部错误修改;
- 控制数据访问权限,保证数据安全和完整性;
- 提高代码的可维护性和健壮性。
8.8 方法、类方法、静态方法的区别
|
方法类型 |
装饰器 |
第一个参数 |
用途 |
|
实例方法 |
无 |
self |
操作对象属性 |
|
类方法 |
@classmethod |
cls |
操作类属性 / 工厂方法 |
|
静态方法 |
@staticmethod |
无 |
工具函数,不依赖类或对象 |
8.9 抽象类与抽象方法(使用 abc 模块)
✅ 什么是抽象类?
抽象类是一种不能被实例化的类,用来定义接口标准,要求子类必须实现指定方法。在python中,抽象类的判断标准为:
满足以下两个条件的类,就是抽象类:
-
继承自
abc.ABC或其子类; -
包含至少一个使用
@abstractmethod装饰的抽象方法。
📌 注意:仅仅使用 @abstractmethod 装饰还不够,必须配合继承 ABC 才能使这个类真正成为抽象类。
✅ 什么是抽象方法?
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪")
抽象方法是没有实现的方法,必须由子类实现,否则子类也变成抽象类。
8.10 多重继承与方法解析顺序(MRO)
✅ 多重继承简介
Python 支持一个类继承多个父类:
class A:
def greet(self):
print("A")
class B:
def greet(self):
print("B")
class C(A, B):
pass
c = C()
c.greet() # 输出:A(优先继承顺序)
⚠ 方法冲突与 C3 线性化算法
当多个父类中存在同名方法时,Python 使用C3 线性化算法确定方法调用顺序(即 MRO:Method Resolution Order)。
你可以通过 .mro() 方法查看,承接上面例子:
print(C.mro())
# 输出:[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
✅ C3 线性化核心原则:
- 子类优先;
- 保持继承顺序;
- 避免重复调用;
- 得到一个无歧义的线性顺序。
8.11 本章小结
|
内容 |
说明 |
|
类 / 对象 |
类是模板,对象是实例 |
|
构造函数 |
__init__() 创建并初始化对象 |
|
析构函数 |
__del__() 释放资源(慎用) |
|
实例属性 |
每个对象独有的属性 |
|
类属性 |
所有对象共享的属性 |
|
私有属性 |
通过名称重整隐藏,保护数据 |
|
继承 |
子类复用父类属性和方法 |
|
方法重写 |
子类重新定义父类方法 |
|
多态 |
同一接口,不同行为,鸭子类型 |
|
封装 |
用私有属性隐藏内部细节 |
|
实例方法 |
操作对象自身属性(含 self) |
|
类方法 |
操作类属性(含 cls) |
|
静态方法 |
与类/对象无关的函数 |
|
抽象类 |
定义接口标准,子类必须实现抽象方法 |
|
多重继承 |
支持多父类,使用 C3 MRO 解决方法冲突 |
732

被折叠的 条评论
为什么被折叠?



