使用超级类的方法

我想学习Python中的super()函数。

虽然我已经掌握了它,直到我通过这个例子(2.6),发现自己卡住了。

http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html#super-with-classmethod-example

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "test.py", line 9, in do_something do_something = classmethod(do_something) TypeError: unbound method do_something() must be called with B instance as first argument (got nothing instead) >>> 

当我在这个例子之前阅读这一行时,并不是我所期望的:

如果我们使用一个类方法,我们没有一个实例来调用super。 幸运的是,对于我们来说,super甚至可以使用types作为第二个参数。 —types可以直接传递给super,如下所示。

这正是Python告诉我的,说do_something()应该用B的一个实例调用是不可能的。

提前致谢

有时,文本必须阅读更多的想法的味道,而不是细节。 这是其中的一种情况。

在链接页面中 ,例do_your_stuff和2.7都应该使用一个方法do_your_stuff 。 (也就是说do_something应该改成do_your_stuff 。)

另外,正如Ned Deily所指出的那样 , A.do_your_stuff必须是一个类方法。

 class A(object): @classmethod def do_your_stuff(cls): print 'This is A' class B(A): @classmethod def do_your_stuff(cls): super(B, cls).do_your_stuff() B.do_your_stuff() 

super(B, cls).do_your_stuff返回一个绑定方法(参见脚注2 )。 因为cls作为super()的第二个parameter passing,所以cls被绑定到返回的方法。 换句话说, cls被作为方法do_you_stuff()的第一个parameter passing。

所以super(B, cls).do_your_stuff()会导致Ado_your_stuff方法被调用,并将cls作为第一个parameter passing。 为了这个工作, Ado_your_stuff必须是一个类方法。 链接的页面没有提到,但这是真的。

PS。 do_something = classmethod(do_something)是创build类方法的老方法。 新的(呃)方法是使用@classmethod装饰器。

来自网页的例子似乎按照发布的方式工作。 您是否为超类创build了do_something方法,但是没有将其变为类方法? 像这样的东西会给你这个错误:

 >>> class A(object): ... def do_something(cls): ... print cls ... # do_something = classmethod(do_something) ... >>> class B(A): ... def do_something(cls): ... super(B, cls).do_something() ... do_something = classmethod(do_something) ... >>> B().do_something() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in do_something TypeError: unbound method do_something() must be called with B instance as first argument (got nothing instead) 

我已经更新了文章,使其更清晰: Python属性和方法#超级

上面使用classmethod的例子显示了什么是类方法 – 它将类本身而不是实例作为第一个parameter passing。 但是你甚至不需要一个实例来调用这个方法,例如:

 >>> class A(object): ... @classmethod ... def foo(cls): ... print cls ... >>> A.foo() # note this is called directly on the class <class '__main__.A'> 

我想我现在已经明白了这一点,感谢这个美丽的网站和可爱的社区。

如果你不介意的话,请纠正我,如果我错误的classmethods(我现在想完全理解):

 # EXAMPLE #1 >>> class A(object): ... def foo(cls): ... print cls ... foo = classmethod(foo) ... >>> a = A() >>> a.foo() # THIS IS THE CLASS ITSELF (__class__) class '__main__.A' # EXAMPLE #2 # SAME AS ABOVE (With new @decorator) >>> class A(object): ... @classmethod ... def foo(cls): ... print cls ... >>> a = A() >>> a.foo() class '__main__.A' # EXAMPLE #3 >>> class B(object): ... def foo(self): ... print self ... >>> b = B() >>> b.foo() # THIS IS THE INSTANCE WITH ADDRESS (self) __main__.B object at 0xb747a8ec >>> 

我希望这个插图显示..

在Python 3中,可以跳过指定super参数,

 class A: @classmethod def f(cls): return "A's f was called." class B(A): @classmethod def f(cls): return super().f() assert Bf() == "A's f was called."