当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时self参数需要显式传递,例如:
class FooParent(object):
def bar(self, message):
print message
class FooChild(FooParent):
def bar(self, message):
FooParent.bar(self, message) #注意,self参数要显式传递
FooChild().bar("Hello, World.")
输出:Hello, World.
其实,这可以用多态来改写,等价于
class FooParent(object):
def bar(self, message):
print message
class FooChild(FooParent):
pass
FooChild().bar("Hello, World.")
这样做有一些缺点,比如说如果修改了父类名称,那么在子类中会涉及多处修改,另外,Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。为了解决这些问题,Python引入了super()机制,例子代码如下:
class FooParent(object):
def bar(self, message):
print(message)
class FooChild(FooParent):
def bar(self, message):
super(FooChild, self).bar(message) #父类是FooParent,使用super(),自动获取FooParent的bar方法
FooChild().bar('Hello, World.')
表面上看 super(FooChild, self).bar(message)方法和FooParent.bar(self, message)方法的结果是一致的,实际上这两种方法的内部处理机制大大不同,当涉及多继承情况时,就会表现出明显的差异来。具体的例子可以参考
关于Python的super用法研究这篇文章。
在来看两个例子,来熟悉super的用法:
class FooParent(object):
def __init__(self):
self.parent='I\'m the parent.'
print 'Parent'
def bar(self, message):
print message, 'from Parent'
class FooChild(FooParent):
def __init__(self):
FooParent.__init__(self)
print 'Child'
def bar(self, message):
FooParent.bar(self, message)
print 'Child bar function. '
print self.parent
if __name__ == '__main__':
fooChild = FooChild()
fooChild.bar("HelloWorld")
用super()机制改写:
class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print 'Parent'
def bar(self, message):
print message, 'from Parent'
class FooChild(FooParent):
def __init__(self):
super(FooChild, self).__init__()
print 'Child'
def bar(self, message):
super(FooChild, self).bar(message)
print 'Child bar function. '
print self.parent
if __name__ == '__main__':
fooChild = FooChild()
fooChild.bar("HelloWorld")
运行结果都是:
下面解释廖博客的一段代码:
目的:
>>> d = Dict(a=1, b=2)
>>> d['a']
1
>>> d.a
1
代码:
class Dict(dict):
def __init__(self, **kw):
<span style="white-space:pre"> </span>super(Dict, self).__init__(**kw)
#调用Dict的父类dict对关键字参数进行处理,super()的固定用法
def __getattr__(self, key):
try:
<span style="white-space:pre"> </span>return self[key] #self是实例名称
except KeyError:
<span style="white-space:pre"> </span>#如果是KeyError即请求一个不存在的字典关键字(即上面的try错误),就抛出下面的错误处理方式
<span style="white-space:pre"> </span>#注意,仅仅是KeyError才能进行下面的raise处理方式,其他错误不处理
<span style="white-space:pre"> </span>raise AttributeError(r"'Dict' object has no attribute '%s'" % key)
#利用raise把一种类型的错误(KeyError)转化成另一种类型(AttributeError),并输出括号中的信息!
def __setattr__(self, key, value):
self[key] = value
关于错误处理的一篇文章: python错误和异常小结