Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用静态方法作为策略设计模式的默认参数?_Python_Python 3.x_Static Methods_Strategy Pattern_Default Parameters - Fatal编程技术网

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

Python 如何使用静态方法作为策略设计模式的默认参数?,python,python-3.x,static-methods,strategy-pattern,default-parameters,Python,Python 3.x,Static Methods,Strategy Pattern,Default Parameters,我想创建一个类,该类使用与以下类似的策略设计模式: class C: @staticmethod def default_concrete_strategy(): print("default") @staticmethod def other_concrete_strategy(): print("other") def __init__(self, strategy=C.default_concrete_strat

我想创建一个类,该类使用与以下类似的策略设计模式:

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()
这会产生以下错误:

name错误:未定义名称“C”
strategy=C.default\u-concrete\u-strategy
替换为
strategy=default\u-concrete\u-strategy
将起作用,但默认情况下,strategy实例变量将是静态方法对象,而不是可调用的方法

TypeError:“staticmethod”对象不可调用
如果我删除
@staticmethod
装饰器,它会起作用,但是还有其他方法吗?我希望默认参数是自我记录的,以便其他人能够立即看到如何包含策略的示例


还有,有没有更好的方法来公开策略而不是静态方法?我认为在这里实现完整类没有意义。

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

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

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
定义方法时,
C
还不存在,因此您可以通过本地名称引用
default\u-concrete\u-strategy
.func
打开
staticmethod
描述符以访问底层原始函数(staticmethod
描述符本身不可调用)

另一种方法是使用哨兵违约<代码>无在这里可以正常工作,因为
策略
的所有正常值都是静态函数:

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

由于这从
self
检索
default\u-concrete\u-strategy
,描述符协议被调用,并且(未绑定)函数在类定义完成后由
staticmethod
描述符本身返回。

策略模式在python中基本上是无用的。因为函数是第一类对象,所以只需传递函数即可。@Bakuriu正如您所见,策略是第一类对象函数。我认为这仍然被称为策略模式不?是的,但是策略模式主要是在不允许传递函数的语言中发明的。我的意思是,在你的类的99%的用例中,你可以简单地直接传递函数,并以较低的复杂性获得相同的结果。@Bakuriu你能举一个例子说明如何做到这一点吗?这也与问题有关,或者他可以先定义
default\u-concrete\u-strategy
,而不用修饰它,然后在定义了
\uuuuu init\uuuuu
之后对其进行装饰(就像2.4之前使用的装饰器一样),尽管这会很麻烦。@Bakuriu:没错;打开包装要容易得多。如果这是唯一的方法,那就太可惜了。如果能在代码中直接看到如何传递参数的示例,那就太好了@Bakuriu在构造函数中修饰方法会有帮助吗?@mtanti否。您必须在类中放置
@staticmethod
。我的意思是
def method():pass;def uuu init uuu(self,func=method):通过;方法=静态方法(方法)
。然而,我必须说,我更喜欢使用
None
作为默认值,并在
\uuu init\uuu
@mtanti中检查它:这不是唯一的方法,但它是最可读的方法。另一种方法是“手工”使用装饰器;定义
default\u-concrete\u策略
而不使用
@staticmethod
行,然后在定义了
\u-init\u\u方法后,使用
default\u-concrete\u策略=staticmethod(default\u-concrete\u策略)