【问题标题】:static method as default parameter to a class method静态方法作为类方法的默认参数
【发布时间】:2026-02-07 15:45:02
【问题描述】:

我的问题是关于另一个问题的两个答案:Using class/static methods as default parameter values within methods of the same class

我试图了解这两个答案的作用是否真的有区别,如果有,各自的优缺点是什么。

问题:如何使用类方法作为同一个类中方法的默认参数。

答案1:使用函数而不是类方法

class X:
    def default_func(x):
        return True

    def test(self, func = default_func):
        return func(self)

答案2:使用类方法,但将其转换为函数

def unstaticmethod(static):
    return static.__get__(None, object)

class X:
    @staticmethod
    def default_func(x):
        return True

    def test(self, func = unstaticmethod(default_func)):
        return func(self)

这最初是用 Python 2 编写的,但我的总结(希望)是 Python 3。

【问题讨论】:

    标签: python static-methods argument-passing


    【解决方案1】:

    答案实际上取决于您对X.default_func 的其他意图。如果您打算在 X 的实例之外调用 X.default_func,那么您希望它是一个静态方法(答案 2)。

    # in other code...
    some_object = "Bring out your dead"
    X.default_func(some_object)
    

    另一方面,如果您不希望 default_func 会被调用,除非在 X 的实例中(当然用作 test 的默认值),我会将答案 1 重写为正确的方法(并使用self 的约定)。

    class X:
        def default_func(self):
            return True
    
        def test(self, func = default_func):
            return func(self)
    

    作为旁注,我想指出您可以用不同的方式编写答案 2 以避免使用非静态方法:

    class X:
        def default_func(x):
            return True
    
        def test(self, func = default_func):
            return func(self)
    
        default_func = staticmethod(default_func)
    

    有效的原因是因为在处理class X: 下的整个块(包括test(func) 的默认参数)之后才创建类X(并且default_func 不会成为X 的方法)。

    【讨论】:

    • 我会感到困惑。如果 default_func 只会在 test() 中被 调用,但 test() 是从类外调用的,我如何从类外调用相当于 "X().test(func= second_func)" 其中 second_func 是 X 的成员函数。
    • Python 2 没有“成员函数”的概念。类及其实例只有方法。如果 "second_func" 是常规实例方法,则需要使用 im_func: X().test(func=X.second_func.im_func) 获取底层函数。我不建议这样做。如果需要动态选择方法,最好将方法名称传递给测试函数,然后在测试中执行getattr(self, func_name)() 之类的操作,然后让 Python 进行实例绑定。