在同一个Python类中调用method,classmethod,staticmethod

时间:2017-11-03 04:28:26

标签: python class

从一个着名的例子中,我在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函数中猜测,如果我对其中任何一个错了,请纠正我。

2 个答案:

答案 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)