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