当前位置:首页>python>想学设计模式但觉得和Python无关?用Python重写23种经典模式里的6个常见模式,码感直接拉升一个水准

想学设计模式但觉得和Python无关?用Python重写23种经典模式里的6个常见模式,码感直接拉升一个水准

  • 2026-10-11 07:54:28
想学设计模式但觉得和Python无关?用Python重写23种经典模式里的6个常见模式,码感直接拉升一个水准

很多人觉得设计模式是Java那帮人搞的那套,跟Python没什么关系。Python太灵活了,什么模式好像都能用几行代码糊弄过去。这话对也不对。糊弄是可以糊弄,用是能用,但写出来的代码好不好改,别人看了骂不骂娘,那又是另一回事。

我挑了6个最常见的模式,用Python重写一遍。不整那些虚头巴脑的UML图,直接看代码。看完你大概会觉得,这些模式在Python里不但不违和,甚至能写得比Java更清爽。

1. 单例模式:别再用模块全局变量了

很多Python新手实现单例,直接在模块里写个全局变量。这确实能工作,但不够干净。真正的单例要控制类的实例化过程。

用__new__方法是最Pythonic的写法。每次实例化时都判断有没有创建过实例。

class Database: 

   _instance = None

   def __new__(cls):

       if cls._instance is None:

           cls._instance = super().__new__(cls)

           cls._instance._init_db()

       return cls._instance

   def _init_db(self):

       self.connection = '连接成功'

db1 = Database()

db2 = Database()

print(db1 is db2)   True

这样写的好处是,调用方根本不用知道自己拿的是单例。该new就new,底层替你管好了。

2. 工厂模式:别再用大段if-else了

工厂模式最怕写成俄罗斯套娃式的if-else。Python的好处是类本身就是对象,可以直接放在字典里。

class Dog: 

   def speak(self): return '汪汪'

class Cat:

   def speak(self): return '喵喵'

class AnimalFactory:

   _animals = {

       'dog': Dog,

       'cat': Cat

   }

   @staticmethod

   def create_animal(animal_type):

       animal_class = AnimalFactory._animals.get(animal_type)

       if not animal_class:

           raise ValueError(f'不认识这个动物: {animal_type}')

       return animal_class()

animal = AnimalFactory.create_animal('dog')

每次加新动物类型,只需要往字典里加一项。不用改核心代码,新来的同事看了直接笑出声。

3. 观察者模式:别用回调地狱了

Python的观察者模式其实很自然,因为函数和类方法都是可调用的。把观察者存成列表,事件触发时一个一个调。

class WeatherStation: 

   def __init__(self):

       self._observers = []

   def register(self, observer):

       self._observers.append(observer)

   def notify(self, data):

       for observer in self._observers:

           observer.update(data)

class DisplayScreen:

   def update(self, data):

       print(f'温度变了: {data['temperature']}度')

station = WeatherStation()

screen = DisplayScreen()

station.register(screen)

station.notify({'temperature': 25})

你要是想省事,甚至可以直接传lambda进去。Python的灵活性让这个模式变得特别轻。

4. 策略模式:别再用switch-case了

策略模式本质是“把算法封装成对象”。Python里最直接的方式就是把函数当策略用。

def quick_sort(data): 

   return sorted(data)

def bubble_sort(data):

   for i in range(len(data)):

       for j in range(0, len(data)-i-1):

           if data[j] > data[j+1]:

               data[j], data[j+1] = data[j+1], data[j]

   return data

class Sorter:

   def __init__(self, strategy=quick_sort):

       self.strategy = strategy

   def sort(self, data):

       return self.strategy(data)

sorter = Sorter(bubble_sort)

print(sorter.sort([3, 1, 2]))

你甚至可以写个字典映射,让用户直接输字符串选策略。用起来灵活,改起来也方便。

5. 装饰器模式:Python原生就支持

其他语言要实现装饰器,得写嵌套类。Python直接有语法糖,太舒服了。

def log_decorator(func): 

   def wrapper(args, kwargs):

       print(f'调用方法: {func.__name__}')

       result = func(args, kwargs)

       print(f'返回结果: {result}')

       return result

   return wrapper

@log_decorator

def add(a, b):

   return a + b

add(1, 2)  

输出: 调用方法: add

输出: 返回结果: 3

这个模式在Python里太常用,以至于很多新手都没意识到这是个设计模式。你写Flask、Django的时候,天天都在用。

6. 代理模式:懒加载和权限控制

代理模式就是给真实对象加个替身。比如一个很重的资源,等到真正用的时候才加载。

class HeavyResource: 

   def load(self):

       print('加载了100M数据')

       return 'heavy data'

class Proxy:

   def __init__(self):

       self._resource = None

   def load(self):

       if self._resource is None:

           self._resource = HeavyResource().load()

       return self._resource

proxy = Proxy()

print(proxy.load())   真正加载

print(proxy.load())   直接返回缓存

Python的上下文管理器也可以当代理用。不过这个写法更直白,新人也看得懂。

这6个模式,每个都在解决一个具体问题。单例管实例,工厂管创建,观察者管通知,策略管算法,装饰器管增强,代理管控制。没有一个是虚无缥缈的。

试着把代码跑一遍,改一改。你会发现这些模式其实就是些套路,谁都能学会。写Python的人掌握了这些东西,写出来的代码会好维护很多。改bug的时候你就知道当初值不值得了。

最新文章

随机文章