python子类调用父类的方法
python子类调用父类的方法
python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找。
继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的。
子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题
如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class A:
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
|
结果:
function b : bbb
Traceback (most recent call last):
File "D:\workbench\python\MyPythonProject\test\study\overwrite_method.py", line 19, in <module>
print b.funca()
File "D:\workbench\python\MyPythonProject\test\study\overwrite_method.py", line 6, in funca
print "function a : %s"%self.namea
AttributeError: B instance has no attribute 'namea'
|
1
2
3
4
5
6
7
8
|
bbb
function b : bbb
Traceback (most recent call last):
File "D:\workbench\python\MyPythonProject\test\study\overwrite_method.py", line 19, in <module>
print b.funca()
File "D:\workbench\python\MyPythonProject\test\study\overwrite_method.py", line 6, in funca
print "function a : %s"%self.namea
AttributeError: B instance has no attribute 'namea'
|
在子类中,构造函数被重写,但新的构造方法没有任何关于初始化父类的namea属性的代码,为了达到预期的效果,子类的构造方法必须调用其父类的构造方法来进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定版本,或者使用super函数。
方法一:调用未绑定的超类构造方法
修改代码,多增一行:
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
#这一行解决了问题
A.__init__(self)
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class A:
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
#这一行解决了问题
A.__init__(self)
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
|
如上有注释的一行解决了该问题,直接使用父类名称调用其构造函数即可。
这种方法叫做调用父类的未绑定的构造方法。在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用类 的方法(比如A.__init),那么就没有实例会被绑定。这样就可以自由的提供需要的self参数,这种方法称为未绑定unbound方法。
通过将当前的实例作为self参数提供给未绑定方法,B类就能使用其父类构造方法的所有实现,从而namea变量被设置。
方法二:使用super函数
修改代码,这次需要增加在原来代码上增加2行:
class A(object):
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
#这一行解决问题
super(B,self).__init__()
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#父类需要继承object对象
class A(object):
def __init__(self):
self.namea="aaa"
def funca(self):
print "function a : %s"%self.namea
class B(A):
def __init__(self):
#这一行解决问题
super(B,self).__init__()
self.nameb="bbb"
def funcb(self):
print "function b : %s"%self.nameb
b=B()
print b.nameb
b.funcb()
b.funca()
|
如上有注释的为新增的代码,其中第一句让类A继承自object类,这样才能使用super函数,因为这是python的“新式类”支持的特性。当前的雷和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。
super函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的父类以及父类的父类。
方法一更直观,方法二可以一次初始化所有超类
super函数比在超累中直接调用未绑定方法更直观,但是其最大的有点是如果子类继承了多个父类,它只需要使用一次super函数就可以。然而如果没有这个需求,直接使用A.__init__(self)更直观一些。
python子类调用父类的方法的更多相关文章
- Python开发基础-Day20继承实现原理、子类调用父类的方法、封装
继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...
- python中子类调用父类的方法
1子类调用父类构造方法 class Animal(object): def __init__(self): print("init Animal class~") def run( ...
- python基础之继承实现原理、子类调用父类的方法、封装
继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...
- Python子类调用父类内属性的方法
常见的就是初始化方法__init__() python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函 ...
- Day7 子类调用父类的方法supper 绑定方法与非绑定方法
supper:可以利用supper来重用父类的方法,可以不用指名道姓的调用了. class OldboyPeople: school = 'oldboy' def __init__(self,name ...
- python对象调用父类的方法
#类定义 class People: #定义基本属性 name = '' age = 0 #定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 #定义构造方法 def __ini ...
- java继承-子类调用父类的方法中包含子类重写的方法
# 看题目是不是很绕,这个我也不知道怎么才能更简单的表达了... # 先看代码: public class Common { public static void main(String[] args ...
- python 子类调用父类成员的方法
1.直接写类名调用: parent_class.parent_attribute(self) class Animal(): def __init__(self, name): self.name = ...
- python 子类调用 父类的构造函数
class A(object): def __init__(self): self.nameaa = 'aa' def funca(self): print('function a %s' % sel ...
随机推荐
- 制作caffe中的test.txt和val.txt
find -name *.jpeg |cut -d '/' -f2-3> train.txt(图片在当前文件夹) find train/dog -name *.JPEG |cut -d '/' ...
- 廖雪峰js教程笔记 1
遍历Array可以采用下标循环,遍历Map和Set就无法使用下标.为了统一集合类型,ES6标准引入了新的iterable类型,Array.Map和Set都属于iterable类型. 具有iterabl ...
- json 入门(1)
1.JSONObject介绍 JSONObject-lib包是一个beans,collections,maps,Java arrays和xml和JSON互相转换的包. 2.下载jar包 http:// ...
- hdu1078 dp(递推)+搜索
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1078 题意:老鼠从(1.1)点出发,每次最多只能走K步,而且下一步走的位置的值必须必当前值 ...
- js与jquery异同
大家都知道jquery是js的一个库,很多东西大多数简写了,让js写起来特别的方便.但是对与学习的人来说,最好是先学会了js再去学jquery会更好.在学得过程中你会发现两者实现的原理是差不多的,但是 ...
- 项目新的需求,网页的自适应交付/响应式交付 Responsive/Adaptive Delivery
网页为什么要做自适应交付,皆因现在移动设备大行其道,现在是移动互联网时代,以IOS及Android为首的各种移动终端已经遍地开花. 当人家用380px的iphone打开你的网页时,你总不能显示个102 ...
- The 2015 China Collegiate Programming Contest K Game Rooms hdu 5550
Game Rooms Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
- Storm on Yarn :原理分析+平台搭建
Storm on YARN: Storm on YARN被视为大规模Web应用与传统企业应用之间的桥梁.它将Storm事件处理平台与YARN(Yet Another Resource Negotiat ...
- 基于Theano的DL的开源小框架:Dragon
Link:https://github.com/neopenx/Dragon 起因 最近看了Hinton的Dropout,发现原来的乱代码只能在Softmax层前面加Dropout.索性把整个Thea ...
- Codeforces #Round 376 F 题解
F. Video Cards time limit per test 1 second memory limit per test 256 megabytes input standard input ...