Python 从另一个classmethod调用classmethod或常规方法的区别

Python 从另一个classmethod调用classmethod或常规方法的区别,python,oop,python-3.x,Python,Oop,Python 3.x,我已经潜伏了很长一段时间,碰巧现在这是我第一次问问题,因为我在任何地方都找不到答案。我真的希望标题不是那么令人困惑,我不知道如何命名它 我正在学习一门矩阵课程,这是我大学项目所需要的(LUP分解、矩阵求逆、解线性方程…)。基本的矩阵运算,操作符重载,一些辅助方法,没什么特别的 在我写代码的时候,我想到了一些困扰我的事情。我有一个私有方法\u makeMatrix。该方法创建预期的矩阵对象。然后,我有类方法,比如createFromList和createFromFile以及类似的基本方法,它们允许

我已经潜伏了很长一段时间,碰巧现在这是我第一次问问题,因为我在任何地方都找不到答案。我真的希望标题不是那么令人困惑,我不知道如何命名它

我正在学习一门矩阵课程,这是我大学项目所需要的(LUP分解、矩阵求逆、解线性方程…)。基本的矩阵运算,操作符重载,一些辅助方法,没什么特别的

在我写代码的时候,我想到了一些困扰我的事情。我有一个私有方法
\u makeMatrix
。该方法创建预期的矩阵对象。然后,我有类方法,比如
createFromList
createFromFile
以及类似的基本方法,它们允许以不同的方式创建矩阵对象。所有这些方法都调用
\u makeMatrix
来实际创建矩阵对象

所以,我的问题是,这两者之间有什么区别,除了在第二种情况下,我可以调用
\u makeMatrix
,而不创建对象(我显然不想这样做,因为
\u makeMatrix
是私有的):


这两种方法之间的确切区别是什么?使用一种或另一种方法是否有任何好处/缺点?

本例中合适的装饰器应该是
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!

因此,每当您在类中需要一个“纯”函数时,即不需要插入该类的任何信息的函数,这应该是一个
静态方法。如果您不想实例化一个对象,但需要类中的一些信息,那么您需要
classmethod

在这两个代码上编写
c.\u makeMatrix(r)
。顺便说一句,根据PEP-8,该对象的正确名称是
cls
What\u makeMatrix在第一种情况下是什么?实例还是静态方法?实例方法需要self作为第一个参数。静态方法需要一个修饰符。@JBernardo Thx,我不知道PEP-8也定义了它@是的,你是对的,我错过了,
self
应该在那里。我已经编辑了我的代码来解决这个问题。@dosvarog现在你的代码不起作用了。。。调用
矩阵时,您将丢失一个参数。\u makeMatrix(r)
@JBernardo是的,您是对的。我当时在用手机,所以前面没有密码。我的原始代码没有
self
,就像您的第三个示例一样。我以前没有意识到这一点,那么这里发生了什么?Python是否隐式地将该方法视为静态方法,即使我没有用
@staticmethod
修饰它?如果我把
self
放在
\u makeMatrix
方法中,我必须用
cls调用它。\u makeMatrix(cls,r)
,所以我猜所有这些调用之间也没有区别,就像前面的例子一样?我不得不承认,所有这些都有点让人困惑。总的来说,我同意你的观点,但这并不能完全回答我的问题。我真正想知道的是,将
\u makeMatrix
定义为classmethod和从
createFromList
cls.\u makeMatrix
那样调用它,或者将它作为实例(常规)方法,从
createFromList
Matrix.\u makeMatrix
?这两个电话有什么区别?这仅仅是语义问题还是Python内部做了一些不同的事情?@dosvarog没有任何区别,因为在这个上下文中
cls
Matrix
。但是编写
cls
(这样子类也可以工作)总是更好的
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!