class A:
def __init__(self):
print "enter A"
print "leave A"
class B(A):
def __init__(self):
print "enter B"
A.__init__(self) # old method
print "leave B"
>>> b = B()
enter B
enter A
leave A
leave B
这样做的缺点是,当一个子类的父类发生变化时(如类B的父类由A变为C时),必须遍历整个类定义,把所有的通过非绑定的方法的类名全部替换过来.
自Python 2.2开始,Python添加了一个关键字super,来解决这个问题。
super(type [, object-or-type])
Return the superclass of type. If the second argument is omitted the super object
returned is unbound. If the second argument is an object, isinstance(obj, type)
must be true. If the second argument is a type, issubclass(type2, type) must be
true. super() only works for new-style classes.
A typical use for calling a cooperative superclass method is:
class C(B):
def meth(self, arg):
super(C, self).meth(arg)
class A(object): # A must be new-style class
def __init__(self):
print "enter A"
print "leave A"
class B(C): # A --> C
def __init__(self):
print "enter B"
super(B, self).__init__()
print "leave B"
1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,产生了一个super对象;
2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;
3. super(B, self).func的调用并不是用于调用当前类的父类的func函数;
4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);
5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。
------------------------------
从super关键字的help我们也能看出来。
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 super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super(C, self).meth(arg)
|
| Methods defined here:
.......
从上面也能看出来,super是一个类,而且是__builtin__模块中的。
---------------------------
从上面的描述来看,super主要是用于调用父类的方法。
那么,在2.2之前的方法也能调用。为啥非得用super呢?
这是因为super能够阻止对父类方法的多次调用。
super,改变了父类搜索顺序, 返回的是一个特殊的父类对象
看例子:
class A: pass class B(A): pass class C(A):pass class D(B, C): pass
这是4个类的基本关系。
假如不使用super,让D的对象调用他们共有的一个方法,会2次调用A中这个方法。