@staticmethod或类外的功能?

时间:2017-11-19 20:55:28

标签: python python-3.x

假设我有class需要一个函数(或者我应该说方法):

  • 独立于我的class实例 - 不需要self参数;
  • 仅在我的class对象中调用
  • 我不需要在任何时候访问它(例如覆盖它);

我应该(A)将它放在class中并将其标记为@staticmethod,还是我应该(B)在我的class对象之外定义它(但在同一命名空间中) ?为什么呢?

示例:

class A:
    def __init__(self, my_int):
        self.my_int = my_int
    def my_int_and_4(self):
        print(self.adder(self.my_int,4))
    @staticmethod
    def adder(a,b):
        return a+b

def adder(a,b):
    return a+b
class B:
    def __init__(self, my_int):
        self.my_int = my_int
    def my_int_and_4(self):
        print(adder(self.my_int,4))

编辑:也许这个例子有点过于简单了。我应该补充一点,我的“adder”版本特别适用于我的class,而不是其他情况。

3 个答案:

答案 0 :(得分:6)

这是私有静态方法的教科书用例。

这里的关键点是你应该把它变成那个类的私有方法。这样你就可以确定没有别的东西可以使用它并依赖于它的实现。您可以在将来更改它,甚至可以删除它,而不会破坏该类之外的任何内容。

是的,让它静止,因为你可以。

在Python中,无法使方法真正成为私有方法,但按照惯例,方法名称前缀为_意味着它应被视为私有。

    @staticmethod
    def _adder(a,b):  ## <-- note the _
        return a+b

如果在某些时候你突然需要在课外使用它,那么暴露它将毫无困难,例如:使用公共包装器方法。

然而,相反的情况并非如此;一旦暴露,很难收回暴露。

答案 1 :(得分:1)

在这种情况下,我肯定会使用私有静态方法,原因是Jean-Francois Corbett描述的原因。 Python中有两种类型的方法属于类本身,而不是实例:类方法和静态方法。

类方法的第一个参数(使用@classmethod创建)以与实例方法(self)的第一个参数引用实例完全相同的方式引用该类。它相当于大多数其他语言中的静态方法。如果您的方法需要访问其他类成员,请使用类方法。

静态方法(使用@staticmethod创建)不包含对类的引用,因此无法引用其他类成员。它通常用于私人帮助方法等。

对于adder方法,我肯定会使用静态方法。但是,在这个修改过的(而且是无用的)版本中,类方法是必要的:

class A:
    x = 1
    def __init__(self, my_int):
        self.my_int = my_int
    def my_int_and_4(self):
        print(self.adder(self.my_int,4))
    @staticmethod
    def _adder(a,b):
        return a+b
    @classmethod
    def _increment(cls, n):
        return n + cls.x

答案 2 :(得分:0)

这两种方法都有效,所以这是可读性和遵循惯例的问题。

  • 该方法是否需要查看实例的私有属性?如果是的话,这是保持在课堂上的一个很好的理由。
  • 该方法仅用作不同方法之一的帮助程序吗?如果是,那么在调用方法之后立即放置它是一个很好的理由,以便可以自上而下地读取代码。
  • 这个方法在你班级的背景之外似乎有意义吗?如果是的话,这是一个很好的理由让它成为一个免费的功能,甚至将它移动到不同的文件,如utils。