我正在努力了解它的用法super()
.从它的外观来看,可以创建两个子类,就好了.
我很想知道以下2个孩子班级之间的实际差异.
class Base(object):
def __init__(self):
print "Base created"
class ChildA(Base):
def __init__(self):
Base.__init__(self)
class ChildB(Base):
def __init__(self):
super(ChildB, self).__init__()
ChildA()
ChildB()
Run Code Online (Sandbox Code Playgroud) 我在阅读泛型时遇到了PECS(制片extends
人和消费者的super
简称).
能否给我一个人解释如何使用佩奇之间解决困惑extends
和super
?
有什么区别:
class Child(SomeBaseClass):
def __init__(self):
super(Child, self).__init__()
Run Code Online (Sandbox Code Playgroud)
和:
class Child(SomeBaseClass):
def __init__(self):
SomeBaseClass.__init__(self)
Run Code Online (Sandbox Code Playgroud)
我已经看到super
在只有单继承的类中使用了很多.我可以看到为什么你在多重继承中使用它,但不清楚在这种情况下使用它的优点是什么.
以下使用super()
引发了一个TypeError:为什么?
>>> from HTMLParser import HTMLParser
>>> class TextParser(HTMLParser):
... def __init__(self):
... super(TextParser, self).__init__()
... self.all_data = []
...
>>> TextParser()
(...)
TypeError: must be type, not classobj
Run Code Online (Sandbox Code Playgroud)
StackOverflow上有一个类似的问题:Python super()引发TypeError,其中错误的解释是用户类不是新式类.但是,上面的类是一个新式的类,因为它继承自object
:
>>> isinstance(HTMLParser(), object)
True
Run Code Online (Sandbox Code Playgroud)
我错过了什么?我怎么用super()
,在这里?
使用HTMLParser.__init__(self)
而不是super(TextParser, self).__init__()
工作,但我想了解TypeError.
PS:Joachim指出,作为一个新式的实例并不等同于一个object
.我多次反复阅读,因此我的困惑(基于object
实例测试的新式类实例测试示例:https://stackoverflow.com/revisions/2655651/3).
我得到一些我无法弄清楚的错误.任何线索我的示例代码有什么问题?
class B:
def meth(self, arg):
print arg
class C(B):
def meth(self, arg):
super(C, self).meth(arg)
print C().meth(1)
Run Code Online (Sandbox Code Playgroud)
我从"超级"内置方法的帮助下得到了示例测试代码."C"级是
这是错误:
Traceback (most recent call last):
File "./test.py", line 10, in ?
print C().meth(1)
File "./test.py", line 8, in meth
super(C, self).meth(arg)
TypeError: super() argument 1 must be type, not classobj
Run Code Online (Sandbox Code Playgroud)
仅供参考,这是来自python本身的帮助(超级):
Help on class super in module __builtin__:
class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound …
Run Code Online (Sandbox Code Playgroud) 如果不将它放在子类的构造函数中,编译器是否会自动放置这个?
那意味着我甚至不需要关心它?在一些文章中,他们把它说出来.
如果我有一个带参数的构造函数,这将是构造函数,还是它需要一个没有参数列表的构造函数?
在Python 3.x中,super()
可以不带参数调用:
class A(object):
def x(self):
print("Hey now")
class B(A):
def x(self):
super().x()
Run Code Online (Sandbox Code Playgroud)
>>> B().x()
Hey now
Run Code Online (Sandbox Code Playgroud)
为了使这项工作,一些编译时间魔法进行,其中的一个后果是,下面的代码(重新绑定super
到super_
)失败:
super_ = super
class A(object):
def x(self):
print("No flipping")
class B(A):
def x(self):
super_().x()
Run Code Online (Sandbox Code Playgroud)
>>> B().x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in x
RuntimeError: super(): __class__ cell not found
Run Code Online (Sandbox Code Playgroud)
super()
如果没有编译器的帮助,为什么无法在运行时解析超类?是否存在这种行为或其潜在原因可能会让一个不知情的程序员陷入困境的实际情况?
...并且,作为一个附带问题:在Python中是否有任何其他函数,方法等示例可以通过将它们重新绑定到不同的名称来打破?
假设我有一个多继承场景:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
Run Code Online (Sandbox Code Playgroud)
有写作两种典型的方法C
的__init__
:
ParentClass.__init__(self)
super(DerivedClass, self).__init__()
但是,在任何一种情况下,如果父类(A
和B
)不遵循相同的约定,则代码将无法正常工作(某些可能会被遗漏,或被多次调用).
那么又是什么样的正确方法呢?很容易说"只是保持一致,遵循一个或另一个",但如果A
或B
来自第三方图书馆,那么呢?有没有一种方法可以确保所有父类构造函数被调用(并且以正确的顺序,只有一次)?
编辑:看看我的意思,如果我这样做:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class …
Run Code Online (Sandbox Code Playgroud) 在Python 2.5中,以下代码引发了TypeError
:
>>> class X:
def a(self):
print "a"
>>> class Y(X):
def a(self):
super(Y,self).a()
print "b"
>>> c = Y()
>>> c.a()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in a
TypeError: super() argument 1 must be type, not classobj
Run Code Online (Sandbox Code Playgroud)
如果我更换class X
用class X(object)
,它会奏效.对此有何解释?
super ×10
python ×7
inheritance ×5
java ×3
oop ×3
class ×1
constructor ×1
generics ×1
object ×1
parent ×1
pecs ×1
python-2.x ×1
python-3.x ×1
superclass ×1
typeerror ×1