使用超级类的方法
我想学习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()
会导致A
的do_your_stuff
方法被调用,并将cls
作为第一个parameter passing。 为了这个工作, A
的do_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."