调用classmethod或来自另一个classmethod的常规方法之间的区别

时间:2015-10-13 21:05:31

标签: python oop python-3.x

我一直潜伏着很长一段时间,现在这是我第一次提出问题,因为我无法在任何地方找到答案。我真的希望标题不会令人困惑,我不知道如何命名它。

我正在研究我的大学项目所需的Matrix课程(LUP分解,矩阵逆,求解线性方程......)。基本矩阵运算,运算符重载,一些辅助方法,没什么太花哨的。

当我编写代码时,我想出了一些困扰我的东西。我有一个私有方法_makeMatrix。该方法创建预期的Matrix对象。然后,我有类createFromListcreateFromFile等类方法,基本上允许以不同的方式创建Matrix对象的方法。所有这些方法都会调用_makeMatrix来实际创建Matrix对象。

所以,我的问题是,这两者之间的区别是什么,除了在第二种情况下我可以在不创建对象的情况下调用_makeMatrix(我显然不希望这样做,因为_makeMatrix是预期的是私人的):

def _makeMatrix(r):
    # some code that creates Matrix object m
    return m

@classmethod
def createFromList(cls, matxList)
    # code that makes matxList suitable for passing to _makeMatrix()
    r = matxList
    return Matrix._makeMatrix(r)

@classmethod
def _makeMatrix(cls, r):
    # some code that creates Matrix object m
    return m

@classmethod
def createFromList(cls, matxList)
    # code that makes matxList suitable for passing to _makeMatrix()
    r = matxList
    return cls._makeMatrix(r)

这两者之间的确切差异是什么?使用一种或另一种方法有任何好处/弊端吗?

1 个答案:

答案 0 :(得分:1)

此示例的正确装饰器应为staticmethod。原因如下:

class MyClass:
    @classmethod
    def foo(cls, arg):
        # Here I can reference the class to work on things related to it
        # even if it is being accessed by an object of this class 
        pass


    @staticmethod
    def bar(arg):
        # This one behaves as a pure function unaware of the class it is
        # located on; even if it is accessed by an object of this class
        pass


    def baz(arg):
        # This one is tricky. Because it has no "self", it should crash
        # when accessed by an object of the class but not on the class
        # itself!
        pass

<强>测试

x = MyClass()
x.foo(10) # OK, but `cls` is unused
x.bar(10) # OK!
x.baz(10) # Crash!!

MyClass.foo(10) # Ok, but `cls` is unused
MyClass.bar(10) # OK!
MyClass.baz(10) # OK!

因此,每当你需要一个类中的“纯”函数,即一个不需要来自类的任何信息的函数时,它应该是staticmethod。如果您不想实例化某个对象但需要该类中的某些信息,则需要classmethod