Python学习之路(12)——绑定方法、未绑定方法以及子类调用父类方法

Python面向对象编程中有三种重要的概念:继承、重写和多态

这里我们主要讨论一下重写的概念。

先看一个例子,假如存在一个基类Person与子类Student,其中子类重写了父类的构造函数__init__(),运行时会报以下错误:

>>> class Person(object):
	def __init__(self):
		self.name = "Tom"
	def getName(self):
		return self.name

	
>>> class Student(Person):
	def __init__(self):
		self.age = 12
	def getAge(self):
		return self.age

	
>>> stu = Student()
>>> stu.getName()
Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    stu.getName()
  File "<pyshell#33>", line 5, in getName
    return self.name
AttributeError: 'Student' object has no attribute 'name'
>>> 

 

这是因为尽管Student类继承了Person类,但是并没有调用父类Person的__init__()方法,那么这种情况下如何调用父类的方法呢?

有两种解决方案:调用未绑定的父类构造方法;使用super()函数。

这里先解释一下什么叫绑定方法和未绑定方法。

bound和unbound方式其实是个很简单的概念。

在讯多语言当中,类似于a.b()这样的调用方法实际是一个整体,但是在Python中,它其实是两部分:获取属性a.b,调用()。所以也可以写成:

c = a.b
c()

  

跟直接调用a.b()是等效的。当a是某个类的实例,b是这个类的方法的时候,a.b的返回值就是bound method,也就是绑定方法。它实际上是bound method对象,这个对象提前将self参数进行了绑定。如示例:

>>> class foo():
	def hehe(self):
		pass

	
>>> foo.hehe
<function foo.hehe at 0x0000000003588C80>
>>> a=foo()
>>> a.hehe
<bound method foo.hehe of <__main__.foo object at 0x0000000003543048>>
>>> foo.hehe()
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    foo.hehe()
TypeError: hehe() missing 1 required positional argument: 'self'
>>>
>>>
>>> a.hehe()
>>>
>>> foo.hehe(a)
>>>

  

相应的,如果A是一个类对象,b是该类的方法,A.b的返回值就是普通函数(Python3.x中为普通函数,Python2.x中为未绑定方法unbound method),这个函数有一个参数self,所以可以用A.b(a)的方式调用,也就是手工将self参数指定为a。这就是unbound method的用法。

 

1、方法一:调用未绑定的父类构造方法

>>> class Person(object):
	def __init__(self):
		self.name = "Tom"
	def getName(self):
		return self.name

>>> class Student(Person):
	def __init__(self):
		Person.__init__(self)        #调用未绑定的父类构造方法
		self.age = 12
	def getAge(self):
		return self.age

>>> stu = Student()
>>> stu.getName()
'Tom'
>>>     

  

2、方法二:使用super()函数

>>> class Person(object):
	def __init__(self):
		self.name = "Tom"
	def getName(self):
		return self.name

>>> class Student(Person):
	def __init__(self):
		super(Student, self).__init__()    # 使用super()函数
		self.age = 12
	def getAge(self):
		return self.age


>>> stu = Student()
>>> stu.getName()
'Tom'

  

super()函数会返回一个super对象,该对象负责进行方法解析,解析过程会自动查找所有的父类以及父类的父类,其最大的优点是如果子类继承了多个父类,只需要使用一次super()函数即可。

而直接调用未绑定方法的方式更加直观。

posted on 2018-02-28 16:19  nicolas_Z  阅读(527)  评论(0)    收藏  举报

导航