Python 面向对象

面向对象编程(OOP)以「对象」为核心组织代码——将数据和处理数据的函数封装为独立模块。Python 从设计之初就是一门面向对象语言。


基本概念

OOP 三个核心特点:

  • 封装:将状态(数据)和行为(方法)包装在一起,隐藏内部实现,对外暴露接口
  • 继承:子类复用父类属性和方法,实现代码复用和层次化设计
  • 多态:不同类的对象对同一消息做出不同响应,提供统一接口

类与对象

定义类

class Dog:
    species = "Canis familiaris"  # 类属性——所有实例共享
 
    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age
 
    def bark(self):       # 实例方法
        return f"{self.name} says woof!"

创建实例

my_dog = Dog("Rex", 3)
print(my_dog.name)       # Rex
print(my_dog.species)    # Canis familiaris
print(my_dog.bark())     # Rex says woof!

__init__

构造函数,创建实例时自动调用。self 代表实例本身:

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

封装

通过私有属性和方法隐藏实现细节。

class Dog:
    def __init__(self, name):
        self.__name = name        # 双下划线 → 私有
 
    def __bark(self):             # 私有方法
        return f"{self.__name} says woof!"
 
    def public_bark(self):        # 公共接口
        return self.__bark()

使用 @property 提供受控访问(见下文 property 章节)。


继承

单继承

class Animal:
    def __init__(self, name):
        self.name = name
 
class Dog(Animal):       # Dog 继承 Animal
    def bark(self):
        return f"{self.name} says woof!"

多继承

Python 支持多继承,但需注意菱形问题(MRO 解决):

class Swimming:
    def swim(self):
        return "Swims!"
 
class Flying:
    def fly(self):
        return "Flies!"
 
class Duck(Swimming, Flying):
    pass
 
duck = Duck()
duck.swim()  # Swims!
duck.fly()   # Flies!

super()

调用父类方法:

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)    # 调用父类构造函数
        self.breed = breed

多态

方法重写

class Animal:
    def sound(self):
        return "Some sound"
 
class Dog(Animal):
    def sound(self):
        return "Woof!"          # 重写
 
class Cat(Animal):
    def sound(self):
        return "Meow!"          # 重写

Duck Typing

Python 是动态类型——不关心对象”是什么”,只关心”能做什么”:

def animal_sound(animal):
    return animal.sound()       # 只要对象有 sound() 方法
 
print(animal_sound(Dog()))      # Woof!
print(animal_sound(Cat()))      # Meow!

抽象类与接口

使用 abc 模块定义抽象基类——不能实例化,子类必须实现抽象方法:

from abc import ABC, abstractmethod
 
class AbstractAnimal(ABC):
    @abstractmethod
    def sound(self):
        pass
 
class Dog(AbstractAnimal):
    def sound(self):            # 必须实现
        return "Woof!"
 
# animal = AbstractAnimal()     # TypeError

对象生命周期

类定义 → 类对象创建 → 实例化 (__new__) → 初始化 (__init__)
    → 属性/方法调用 → 销毁 (__del__) → GC 回收
  • __new__:分配内存(极少需要重写)
  • __init__:初始化实例
  • __del__:实例销毁时调用(通常依赖 GC,不手动清理)

魔术方法一览

魔术方法(dunder methods)以双下划线包裹,为对象提供内置行为。

表示方法

方法用途触发
__str__用户友好的字符串表示str()print()
__repr__开发者用的”官方”表示repr()、交互环境
__format__格式化字符串f"{obj:spec}"

数学运算

运算符魔术方法
+__add__
-__sub__
*__mul__
/__truediv__
//__floordiv__
%__mod__
**__pow__
@__matmul__
class Vector:
    def __init__(self, x, y):
        self.x, self.y = x, y
 
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
 
v = Vector(1, 2) + Vector(2, 3)
# v.x=3, v.y=5

比较运算

运算符魔术方法
==__eq__
!=__ne__
<__lt__
<=__le__
>__gt__
>=__ge__

容器方法

方法用途
__len__len(obj)
__getitem__obj[key] 读取
__setitem__obj[key] = val
__delitem__del obj[key]
__iter__返回迭代器
__next__迭代下一项
__contains__x in obj

迭代器示例:

class Counter:
    def __init__(self, start, end):
        self.current, self.end = start, end
 
    def __iter__(self):
        return self
 
    def __next__(self):
        if self.current >= self.end:
            raise StopIteration
        value = self.current
        self.current += 1
        return value
 
for n in Counter(1, 4):
    print(n)  # 1, 2, 3

属性访问

方法触发时机
__getattr__访问不存在的属性
__getattribute__访问任何属性(优先于 __getattr__
__setattr__设置任何属性
__delattr__删除属性
class MyClass:
    def __setattr__(self, name, value):
        self.__dict__[name] = value  # 防止递归
 
    def __getattr__(self, name):
        return f"{name} 不存在"

上下文管理

class FileManager:
    def __init__(self, filename):
        self.filename = filename
 
    def __enter__(self):
        self.file = open(self.filename, 'r')
        return self.file
 
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()
        # 返回 True 可抑制异常
 
with FileManager("data.txt") as f:
    content = f.read()

可调用对象 __call__

class Greeter:
    def __init__(self, greeting="Hello"):
        self.greeting = greeting
 
    def __call__(self, name):
        return f"{self.greeting}, {name}!"
 
hello = Greeter("Hello")
hello("John")  # "Hello, John!"

类型转换与判断

方法触发
__int__int(obj)
__float__float(obj)
__bytes__bytes(obj)
__bool__bool(obj)if obj:
__hash__hash(obj)(用于 dict key/set)

定义了 __eq__ 但未定义 __hash__ 的对象不可哈希。不可变对象才应实现 __hash__


描述符

实现了 __get__ / __set__ / __delete__ 的对象,用于控制属性访问:

class Descriptor:
    def __get__(self, instance, owner):
        return instance.__dict__.get(self.name)
 
    def __set__(self, instance, value):
        instance.__dict__[self.name] = value

property 就是 Python 内置的描述符实现(见下文)。


类方法与静态方法

class Example:
    class_var = "Class Variable"
 
    def instance_method(self):     # 需要实例
        return self
 
    @classmethod
    def class_method(cls):         # 需要类
        return cls.class_var
 
    @staticmethod
    def static_method():           # 不需要类或实例
        return "utility"
类型第一个参数可访问适用场景
实例方法self实例 + 类属性操作实例数据
类方法cls类属性工厂方法、继承
静态方法工具函数

property

@property 让方法像属性一样访问,同时保持控制逻辑:

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius
 
    @property
    def celsius(self):
        return self._celsius
 
    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("温度不能低于绝对零度")
        self._celsius = value
 
    @celsius.deleter
    def celsius(self):
        del self._celsius
 
t = Temperature(25)
print(t.celsius)     # 25 — 像属性一样读取
t.celsius = 30       # 像属性一样赋值(触发 setter)

属性保护约定

  • _name:单下划线 → 受保护(约定,仍可访问)
  • __name:双下划线 → 名称修饰(_ClassName__name),更难外部访问

__slots__

限制实例可拥有的属性,节省内存(大量实例时有效):

class Point:
    __slots__ = ['x', 'y']
 
    def __init__(self, x, y):
        self.x, self.y = x, y
 
p = Point(1, 2)
p.z = 3  # AttributeError

代价:不能动态添加属性,不支持 __dict__,与某些 ORM/序列化库可能冲突。


关联