从一个着名的例子中,我在Python类中学习了method,classmethod和staticmethod之间的区别。
来源: What is the difference between @staticmethod and @classmethod in Python?
class A(object):
def foo(self,x):
print "executing foo(%s,%s)"%(self,x)
@classmethod
def class_foo(cls,x):
print "executing class_foo(%s,%s)"%(cls,x)
@staticmethod
def static_foo(x):
print "executing static_foo(%s)"%x
# My Guesses
def My_Question(self,x):
self.foo(x)
A.class_foo(x)
A.static_foo(x)
a=A()
现在我想知道如何在课程中调用方法@classmethod
和@staticmethod
。
我在上面的My_Question
函数中猜测,如果我对其中任何一个错了,请纠正我。
答案 0 :(得分:2)
是的,你的猜测会有效。请注意,在类之外调用staticmethods和classmethods 也是可能的/正常的:
class A():
...
A.class_foo()
A.static_foo()
还要注意里面的常规实例方法,习惯上直接在实例(self
)而不是类(A
)上调用staticmethods和类方法:
class A():
def instance_method(self):
self.class_foo()
self.static_foo()
这允许继承按预期工作 - 如果我从B
创建A
子类,如果我调用B.instance_method()
,我的class_foo
函数将获得B
而不是A
作为cls
参数 - 如果我覆盖static_foo
上的B
做一些与A.static_foo
略有不同的事情,这将允许调用被覆盖的版本。
一些例子可能会更清楚:
class A(object):
@staticmethod
def static():
print("Static, in A")
@staticmethod
def staticoverride():
print("Static, in A, overrideable")
@classmethod
def clsmethod(cls):
print("class, in A", cls)
@classmethod
def clsmethodoverrideable(cls):
print("class, in A, overridable", cls)
def instance_method(self):
self.static()
self.staticoverride()
self.clsmethod()
self.clsmethodoverride()
class B(A):
@classmethod
def clsmethodoverrideable(cls):
print("class, in B, overridable", cls)
@staticmethod
def staticoverride():
print("Static, in B, overrideable")
a = A()
b = B()
a.instance_method()
b.instance_method()
...
运行之后,通过将self.
内的所有A.
更改为instance_method
来尝试。重新运行并进行比较。您会看到B
的所有引用都已消失(即使您正在调用b.instance_method()
)。这就是您希望使用self
而不是类的原因。
答案 1 :(得分:1)
正如@wim所说,你拥有的是正确的。这是调用My_Question
时的输出。
>>> a.My_Question("My_Answer=D")
executing foo(<__main__.A object at 0x0000015790FF4668>,My_Answer=D)
executing class_foo(<class '__main__.A'>,My_Answer=D)
executing static_foo(My_Answer=D)