133 字
1 分钟
Python 面向对象与设计模式
一、类变量与实例变量
1.1 核心区别
class Dog: kind = "dog" # 类变量:所有实例共享
def __init__(self, name): self.name = name # 实例变量:每个实例独立
d1 = Dog("旺财")d2 = Dog("小白")
print(d1.kind) # dog - 通过实例查找print(d2.kind) # dogprint(Dog.kind) # dog - 通过类访问
d1.kind = "big dog" # 创建实例变量,不影响类print(d1.kind) # big dog (实例变量)print(d2.kind) # dog (类变量)print(Dog.kind) # dog (类变量不变)1.2 可变对象陷阱
# 可变对象作为类变量的危险class Registry: items = [] # 所有实例共享同一个列表!
r1 = Registry()r2 = Registry()
r1.items.append("item1")print(r2.items) # ['item1'] - 意外共享!
# 正确做法:使用实例变量class RegistryFixed: def __init__(self): self.items = [] # 每个实例独立列表
def add(self, item): self.items.append(item)
r1 = RegistryFixed()r2 = RegistryFixed()
r1.items.append("item1")print(r2.items) # [] - 独立列表1.3 property 装饰器
class Circle: def __init__(self, radius): self._radius = radius # 私有属性
@property def radius(self): return self._radius
@radius.setter def radius(self, value): if value < 0: raise ValueError("半径不能为负数") self._radius = value
@property def area(self): return 3.14159 * self._radius ** 2
c = Circle(5)print(c.radius) # 5print(c.area) # 78.53975c.radius = 10print(c.area) # 314.159二、继承与 MRO
2.1 方法解析顺序
class A: def method(self): return "A"
class B(A): def method(self): return "B"
class C(A): def method(self): return "C"
class D(B, C): pass
d = D()print(d.method()) # "B" - 按 MRO 顺序优先使用 B
# 查看 MROprint(D.__mro__)# (<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)2.2 super() 的工作原理
class Base: def __init__(self): print("Base init")
class Child(Base): def __init__(self): super().__init__() # 调用父类 print("Child init")
# super() 沿着 MRO 顺序查找class A: def method(self): print("A")
class B(A): def method(self): super().method() print("B")
class C(A): def method(self): super().method() print("C")
class D(B, C): def method(self): super().method() print("D")
D().method()# 输出: A C B D# MRO: D -> B -> C -> A2.3 多继承的菱形问题
# 菱形继承class Base: def method(self): print("Base")
class Left(Base): pass
class Right(Base): def method(self): print("Right")
class Child(Left, Right): pass
Child().method() # 无输出!Left 优先于 Right
# Python 3 使用 C3 线性化算法# MRO: Child -> Left -> Right -> Base -> object
# 明确调用class Child(Left, Right): def method(self): super().method() # 调用 Left,然后 Right,然后 Base三、常见设计模式
3.1 单例模式
# 方式1: __new__ 方法class Singleton: _instance = None
def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance
# 方式2: 装饰器def singleton(cls): instances = {}
def get_instance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls]
return get_instance
@singletonclass Database: pass
# 方式3: 元类class SingletonMeta(type): _instances = {}
def __call__(cls, *args, **kwargs): if cls not in cls._instances: cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls]
class Database(metaclass=SingletonMeta): pass
# 方式4: 模块级单例(最简单)# mysingleton.pyclass _MySingleton: passsingleton = _MySingleton()3.2 工厂模式
# 简单工厂class Dog: def speak(self): return "汪汪"
class Cat: def speak(self): return "喵喵"
class Factory: @staticmethod def create(animal_type): animals = {"dog": Dog, "cat": Cat} return animals[animal_type]()
factory = Factory()animal = factory.create("dog")print(animal.speak()) # 汪汪
# 工厂方法模式class Animal: def speak(self): raise NotImplementedError
class AnimalFactory: def create(self): raise NotImplementedError
class DogFactory(AnimalFactory): def create(self): return Dog()
# 抽象工厂class AbstractFactory: def create_product_a(self): pass def create_product_b(self): pass3.3 观察者模式
class Subject: def __init__(self): self._observers = []
def attach(self, observer): self._observers.append(observer)
def detach(self, observer): self._observers.remove(observer)
def notify(self, message): for observer in self._observers: observer.update(message)
class Observer: def update(self, message): print(f"收到通知: {message}")
subject = Subject()observer = Observer()subject.attach(observer)subject.notify("Hello") # 收到通知: Hello3.4 策略模式
class SortStrategy: def sort(self, data): raise NotImplementedError
class QuickSort(SortStrategy): def sort(self, data): return sorted(data)
class MergeSort(SortStrategy): def sort(self, data): return sorted(data, reverse=True)
class Context: def __init__(self, strategy): self.strategy = strategy
def execute(self, data): return self.strategy.sort(data)
context = Context(QuickSort())print(context.execute([3, 1, 2])) # [1, 2, 3]3.5 装饰器模式
# 组合优于继承class Component: def operation(self): return "原始"
class Decorator(Component): def __init__(self, wrapped): self._wrapped = wrapped
def operation(self): return f"装饰({self._wrapped.operation()})"
component = Component()decorated = Decorator(component)print(decorated.operation()) # 装饰(原始)3.6 迭代器模式
class TreeNode: def __init__(self, value, left=None, right=None): self.value = value self.left = left self.right = right
class Tree: def __init__(self, root): self.root = root
def __iter__(self): # 中序遍历 def inorder(node): if node is None: return yield from inorder(node.left) yield node.value yield from inorder(node.right)
yield from inorder(self.root)
# 使用root = TreeNode(1, TreeNode(2), TreeNode(3))tree = Tree(root)for value in tree: print(value) # 2, 1, 3四、魔术方法
4.1 常用魔术方法
class Vector: def __init__(self, x, y): self.x = x self.y = y
# 字符串表示 def __repr__(self): return f"Vector({self.x}, {self.y})" def __str__(self): return f"({self.x}, {self.y})"
# 比较运算符 def __eq__(self, other): return self.x == other.x and self.y == other.y def __lt__(self, other): return self.x < other.x or (self.x == other.x and self.y < other.y)
# 算术运算符 def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __sub__(self, other): return Vector(self.x - other.x, self.y - other.y) def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar)
# 可调用 def __call__(self): return f"Vector({self.x}, {self.y})"
# 长度 def __len__(self): return 2
# 索引访问 def __getitem__(self, index): if index == 0: return self.x if index == 1: return self.y raise IndexError4.2 容器协议
class CustomList: def __init__(self, items): self.items = items
def __len__(self): return len(self.items) def __getitem__(self, i): return self.items[i] def __setitem__(self, i, v): self.items[i] = v def __contains__(self, v): return v in self.items def __iter__(self): return iter(self.items) def __add__(self, other): return CustomList(self.items + other.items)五、接口与抽象基类
5.1 抽象基类
from abc import ABC, abstractmethod
class Shape(ABC): @abstractmethod def area(self): pass
@abstractmethod def perimeter(self): pass
def display(self): print(f"Area: {self.area()}")
class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height
def area(self): return self.width * self.height def perimeter(self): return 2 * (self.width + self.height)
# 不能实例化抽象类# shape = Shape() # TypeError
rect = Rectangle(5, 3)rect.display() # Area: 155.2 Protocol (Python 3.8+)
from typing import Protocol
class Drawable(Protocol): def draw(self) -> None: ...
class Circle: def draw(self) -> None: print("Drawing circle")
def render(d: Drawable) -> None: d.draw()
render(Circle()) # 有效,Circle 实现了 draw 方法支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
Python 面向对象与设计模式
https://blog.souloss.com/posts/interview/python-oop/ 部分信息可能已经过时
相关文章 智能推荐






