super继承和普通父类继承

当存在继承关系的时候,有时候需要在子类中调用父类的方法,此时最简单的方法是把对象调用转换成类调用,需要注意的是这时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错误和异常小结


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值