python类设计(staticmethod vs方法)

时间:2011-03-06 17:21:31

标签: python static-methods oop

对于不需要任何传递信息(对象实例或类)的方法,更好的方法是什么,因为例如它们只是进行简单的转换。 @staticmethod 方法

class Foo(object):
    def __init__(self, trees):
        self.money = Foo.trees2money(trees)

    @staticmethod
    def trees2money(trees):
        return trees * 1.337

class Quu(object):
    def __init__(self, trees):
        self.money = self.trees2money(trees)

    def trees2money(self, trees):
        return trees * 1.337

3 个答案:

答案 0 :(得分:8)

方法类型的选择取决于其他因素。

你有两个案例。第一种情况是该方法必须是类接口的一部分 - 例如它必须由用户调用,或者它必须在子类中可以覆盖,或者它使用self中的信息,或者很可能在软件的未来版本中你可能需要这些信息。

在第一种情况下,您经常使用普通方法(这是方法与实例相关而不是与类相关)或classmethod(当方法与类相关时,例如它替代构造函数,发现类特征的方法等)。在这两种情况下,如果方法不使用类/实例中的信息,则可以使用staticmethod,但是这样做并没有获得任何结果。它也会破坏你cls.method(instance, *args)的能力,而staticmethod已经太多了,无法获得任何东西。

第二种情况是该方法不以任何方式成为该类的一部分。然后通常建议使用一个函数 - 该方法实际上不是接口的一部分,因此它没有位置。您的示例似乎就是这种情况,除非您想要覆盖子类中的树/钱计算器,但这在很大程度上取决于您正在使用它做什么。

一个特殊情况是私有方法 - 那么你可能想要使用一个方法,即使它与类没有真正的关系,私有方法也不是接口的一部分,所以你把它们放在哪里并不重要。使用staticmethod仍然不会让你获得太多,但也没有任何理由不使用它。

实际上有一种情况class Foo(object): trees2money = staticmethod(calculators.trees2money) foo = staticmethod(calculators.bar) 非常有用 - 当你在课堂上放置外部函数(或其他对象)时。

class Foo(object):
     def trees2money(self, trees):
         """Calculator for trees2money, you can override when subclassing"""
         return calculators.trees2money(trees)
     @property
     def foo(self):
         """The foo of the object"""
         return calculators.bar

但是当你有一个静态的类定义时,那并不是很好,因为你可以总是这样做。

{{1}}

这使您可以更好地了解这些对象在阅读源代码时的作用,甚至允许您添加文档。但是当你动态构建类时,或者你在一个元类中添加它们时,它仍然可以派上用场(手动创建一个包装器方法不是很方便)。

答案 1 :(得分:2)

对于所有面向对象的设计,我的一般规则是,如果一个类没有状态,请考虑使用静态方法。如果类具有状态,请使用实例方法 - 放下手。

此外,如果类确实没有状态,请反映几分钟,看看是否无法将静态行为移近数据,从而消除了Extract Method重构的静态方法。

答案 2 :(得分:0)

任何不使用对象命名空间中的名称的方法应该是classmethods,而那些不使用类命名空间名称的方法 - staticmetdods,甚至可以作为函数放在模块级别。

当使用实际的对象方法时,预期的行为是访问同一对象的其他一些attrubutes /方法。