不对作用于对象数据的方法是否应该是静态的?

时间:2017-10-09 15:00:35

标签: python static

我有一个类,其中包含一些不对对象数据进行操作的辅助函数。通常我会把这些方法保密,但我是Python,所以没有这样的东西。在测试中,我发现必须实例化我的类的实例以便能够调用这些方法有点傻。有理由选择将这些方法保持为非静态或使其静态吗?

2 个答案:

答案 0 :(得分:2)

如果方法不需要访问当前实例,您可能想要使用classmethod,staticmethod或plain函数。

classmethod将当前类作为第一个参数。这使它能够访问类属性,包括其他类方法或staticmethods 。如果您的方法需要调用其他classmethods或staticmethods,这是正确的选择。

静态方法只能获得它的显式参数 - 实际上它只是一个可以在类或实例上解析的函数。静态方法的要点是专门化 - 你可以覆盖子类中的static方法,并让基类的方法(classmethod或instancemethod)调用静态方法的重写版本 - 并最终易于使用 - 你不要需要在课堂之外导入这个功能(此时它接近于懒惰,但我有一些动态导入的情况等,它恰好很方便)。

普通函数是一个简单的函数 - 没有基于类的调度,没有继承,没有花哨的东西。但是,如果它只是同一模块中几个类内部使用的辅助函数,而不是类或模块API的一部分,那么它可能就是你正在寻找的东西。

作为最后一点:你可以有某种"某种" Python中的隐私。大多数情况下,使用单个前导下划线为名称(属性/方法/类或普通函数)添加前缀意味着"这是一个实现细节,它不是API的一部分,您不是甚至应该知道它存在,它可能会在没有通知的情况下改变或消失,所以如果你使用它并且你的代码破坏那么它就是你的问题"。

答案 1 :(得分:1)

如果你想仅仅出于结构原因在课堂上保留所述方法,你可以使用@staticmethod装饰器将它们设为静态:

class Foo():

    @staticmethod
    def my_static_method(*args, **kwargs):
         ....

您的第一个参数不会被解释为对象本身,您可以从类或该类的对象中使用它。如果您仍然需要在方法中访问类属性,则可以将其设为类方法:

class Bar():

    counter = 0

    @classmethod
    def my_class_method(cls, *args, **kwargs):
        cls.counter += 1
        ...

类方法的第一个参数显然是类而不是实例。

如果你不使用任何类或实例属性,我看不到"理论"有理由不让它们变得静止。某些IDE甚至将此突出显示为一个软警告,如果它不使用或改变任何类/实例属性,则会提示您使该方法保持静态。