在2009年Wikipedia中的Strategy Pattern条目中,有一个用PHP编写的示例。
大多数其他代码示例执行以下操作:
a = Context.new(StrategyA.new) a.execute #=> Doing the task the normal way b = Context.new(StrategyB.new) b.execute #=> Doing the task alternatively c = Context.new(StrategyC.new) c.execute #=> Doing the task even more alternative
在Python代码中,“提交”按钮使用了另一种技术。我不知道Python代码是否也会像其他代码示例那样执行。
更新: 在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 execution Strategy 1 Strategy 2
主要区别在于:
if func == None
请注意,有3种方法可以在Python中动态添加方法:
我给你看的方式 但是该方法将是静态的,不会传递“ self”参数。
使用类名:
StrategyExample.execute = func
在这里,所有实例都将func作为execute方法,并self作为参数传递。
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以争论的形式通过。
strat0
start0.execute()
如果需要在函数中使用对当前实例的引用,则可以合并第一个和最后一个方法。如果你不:
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 sys import types if sys.version_info[0] > 2: # Python 3+ create_bound_method = types.MethodType else: 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 0 Strategy Example 1 from execute 1 Strategy Example 2 from execute 2
当然,在这些功能不能再单独使用的情况下,但是仍然可以绑定到任何对象的任何其他实例,而没有任何接口限制。