如何将静态方法用作策略设计模式的默认参数?

mta*_*nti 6 python static-methods strategy-pattern default-parameters python-3.x

我想创建一个使用类似于此的策略设计模式的类:

class C:

    @staticmethod
    def default_concrete_strategy():
        print("default")

    @staticmethod
    def other_concrete_strategy():
        print("other")

    def __init__(self, strategy=C.default_concrete_strategy):
        self.strategy = strategy

    def execute(self):
        self.strategy()
Run Code Online (Sandbox Code Playgroud)

这给出了错误:

NameError: name 'C' is not defined
Run Code Online (Sandbox Code Playgroud)

替换strategy=C.default_concrete_strategy为strategy=default_concrete_strategy将工作但是,默认情况下,策略实例变量将是静态方法对象而不是可调用方法.

TypeError: 'staticmethod' object is not callable
Run Code Online (Sandbox Code Playgroud)

如果我删除@staticmethod装饰器它会工作,但还有其他方法吗?我希望自己记录默认参数,以便其他人立即看到如何包含策略的示例.

此外,是否有更好的方法来公开策略而不是静态方法?我不认为实现完整的课程在这里有意义.

Mar*_*ers 10

不,您不能,因为该class定义尚未完成运行,因此当前名称空间中尚未存在类名.

您可以直接使用函数对象:

class C:    
    @staticmethod
    def default_concrete_strategy():
        print("default")

    @staticmethod
    def other_concrete_strategy():
        print("other")

    def __init__(self, strategy=default_concrete_strategy.__func__):
        self.strategy = strategy
Run Code Online (Sandbox Code Playgroud)

C在定义方法时尚不存在,因此您可以default_concrete_strategy通过本地名称来引用..__func__展开staticmethod描述符以访问底层原始函数(staticmethod描述符本身不可调用).

另一种方法是使用哨兵默认值; None这里工作正常,因为所有正常值strategy都是静态函数:

class C:    
    @staticmethod
    def default_concrete_strategy():
        print("default")

    @staticmethod
    def other_concrete_strategy():
        print("other")

    def __init__(self, strategy=None):
        if strategy is None:
            strategy = self.default_concrete_strategy
        self.strategy = strategy
Run Code Online (Sandbox Code Playgroud)

由于default_concrete_strategy从self描述符协议检索,因此staticmethod在类定义完成之后,描述符本身将返回(未绑定)函数.