如何用不同于Wikipedia中示例的方式在Python中编写策略模式?

如何用不同于Wikipedia中示例的方式在Python中编写策略模式?,第1张

如何用不同于Wikipedia中示例的方式在Python中编写策略模式?

Python中的示例与其他示例并无太大不同。模拟PHP脚本:

class StrategyExample:    def __init__(self, func=None):        if func:  self.execute = func    def execute(self):        print("Original execution")def executeReplacement1():    print("Strategy 1")def executeReplacement2():    print("Strategy 2")if __name__ == "__main__":    strat0 = StrategyExample()    strat1 = StrategyExample(executeReplacement1)    strat2 = StrategyExample(executeReplacement2)    strat0.execute()    strat1.execute()    strat2.execute()

输出:

Original executionStrategy 1Strategy 2

主要区别在于:

  • 您无需编写任何其他类或实现任何接口。
  • 相反,您可以传递将绑定到所需方法的函数引用。
  • 这些函数仍然可以单独使用,并且如果您愿意,原始对象可以具有默认行为(该
    if func == None
    模式可以用于该行为)。
  • 确实,它和Python一样干净简洁,优雅。但是你会丢失信息;由于没有显式接口,因此假定程序员是成年人,知道他们在做什么。

请注意,有3种方法可以在Python中动态添加方法:

  • 我给你看的方式 但是该方法将是静态的,不会传递“ self”参数。

  • 使用类名:

StrategyExample.execute = func

在这里,所有实例都将

func
作为
execute
方法,并
self
作为参数传递。

  • 绑定到实例(使用
    types
    模块):

strat0.execute = types.MethodType(executeReplacement1, strat0)

或使用Python 2,还需要更改实例的类:

strat0.execute = types.MethodType(executeReplacement1, strat0,StrategyExample)

与第一个示例一样,这会将新方法绑定到

strat0
和only
strat0
。但是
start0.execute()
self
以争论的形式通过。

如果需要在函数中使用对当前实例的引用,则可以合并第一个和最后一个方法。如果你不:

class StrategyExample:    def __init__(self, func=None):        self.name = "Strategy Example 0"        if func:  self.execute = func    def execute(self):        print(self.name)def executeReplacement1():    print(self.name + " from execute 1")def executeReplacement2():    print(self.name + " from execute 2")if __name__ == "__main__":    strat0 = StrategyExample()    strat1 = StrategyExample(executeReplacement1)    strat1.name = "Strategy Example 1"    strat2 = StrategyExample(executeReplacement2)    strat2.name = "Strategy Example 2"    strat0.execute()    strat1.execute()    strat2.execute()

你会得到:

Traceback (most recent call last):  File "test.py", line 28, in <module>    strat1.execute()  File "test.py", line 13, in executeReplacement1    print self.name + " from execute 1"NameError: global name 'self' is not defined

因此正确的代码将是:

import sysimport typesif sys.version_info[0] > 2:  # Python 3+    create_bound_method = types.MethodTypeelse:    def create_bound_method(func, obj):        return types.MethodType(func, obj, obj.__class__)class StrategyExample:    def __init__(self, func=None):        self.name = "Strategy Example 0"        if func:  self.execute = create_bound_method(func, self)    def execute(self):        print(self.name)def executeReplacement1(self):    print(self.name + " from execute 1")def executeReplacement2(self):    print(self.name + " from execute 2")if __name__ == "__main__":    strat0 = StrategyExample()    strat1 = StrategyExample(executeReplacement1)    strat1.name = "Strategy Example 1"    strat2 = StrategyExample(executeReplacement2)    strat2.name = "Strategy Example 2"    strat0.execute()    strat1.execute()    strat2.execute()

这将输出预期的结果:

Strategy Example 0Strategy Example 1 from execute 1Strategy Example 2 from execute 2

当然,在这些功能不能再单独使用的情况下,但是仍然可以绑定到任何对象的任何其他实例,而没有任何接口限制。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5662595.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存