python优雅实现策略模式

本文介绍了一个使用Python实现的策略模式示例,展示了如何通过注入不同的函数来改变对象的行为,利用Python的高阶函数特性实现了灵活的策略切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

优雅实现策略模式; 在awesome-python上有一个关于模式设计的包,对包中的代码做了一点修改。BaseStrateby最核心的方法是select.


# -*- coding: utf-8 -*-
"""
http://stackoverflow.com/questions/963965/how-is-this-strategy-pattern
 -written-in-python-the-sample-in-wikipedia
In most of other languages Strategy pattern is implemented via creating some
base strategy interface/abstract class and subclassing it with a number of
concrete strategies (as we can see at
http://en.wikipedia.org/wiki/Strategy_pattern), however Python supports
higher-order functions and allows us to have only one class and inject
functions into it's instances, as shown in this example.
"""
import types
import random


class BaseStrategy:

    def __init__(self, func=None):
        if func is not None:
            self.select(func)

    def __call__(self, *args, **kwargs):
        self.execute(*args, **kwargs)

    def execute(self, *args, **kwargs):
        pass

    def select(self, func):
        # redefine a method
        self.execute = types.MethodType(func, self)

class StrategyExample(BaseStrategy):

    def __init__(self, func=None):
        self.name = 'Strategy Example 0'
        if func is not None:
            self.select(func)


    def execute(self, arg='nothing'):
        print(arg)

    def make(self):
        self.select(execute_replacement1)

    def random(self):
        r = random.random()
        if r > 0.5:
            self.select(execute_replacement1)
        else:
            self.select(execute_replacement2)


# strategies
def execute_replacement1(obj, s=' from execute'):
    print(obj.name + s + '1')


def execute_replacement2(obj, s=' from execute'):
    print(obj.name + s + '2')


class SubStrategy(StrategyExample):
    def __init__(self, func=None):
        super(SubStrategy, self).__init__(func)
        self.name = 'Strategy Example x'


if __name__ == '__main__':
    strat0 = StrategyExample()

    stratx = SubStrategy()
    stratx()

    strat1 = StrategyExample(execute_replacement1)
    strat1.name = 'Strategy Example 1'

    strat2 = StrategyExample(execute_replacement2)
    strat2.name = 'Strategy Example 2'

    strat0()
    strat1()
    strat2()
    strat2.select(execute_replacement1)
    strat2()
    
    for k  in range(5):
        stratx = SubStrategy()
        stratx.random()
        stratx('shit')

### OUTPUT ###
# nothing
# nothing
# Strategy Example 1 from execute 1
# Strategy Example 2 from execute 2
# Strategy Example 2 from execute 1
# Strategy Example xshit
# Strategy Example xshit
# Strategy Example xshit
# Strategy Example xshit
# Strategy Example xshit


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值