python子类调用父类的方法

python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找。

继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的。

子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题

如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。

 
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()

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()

结果:

 
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'
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函数。

方法一:调用未绑定的超类构造方法

修改代码,多增一行:

 
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()

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行:

 
#父类需要继承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()

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子类调用父类的方法的更多相关文章

  1. Python开发基础-Day20继承实现原理、子类调用父类的方法、封装

    继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...

  2. python中子类调用父类的方法

    1子类调用父类构造方法 class Animal(object): def __init__(self): print("init Animal class~") def run( ...

  3. python基础之继承实现原理、子类调用父类的方法、封装

    继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...

  4. Python子类调用父类内属性的方法

    常见的就是初始化方法__init__() python中类的初始化方法是__init__(),因此父类子类的初始化方法都是这个,如果子类不实现这个函数,初始化时调用父类的初始化函数,如果子类实现这个函 ...

  5. Day7 子类调用父类的方法supper 绑定方法与非绑定方法

    supper:可以利用supper来重用父类的方法,可以不用指名道姓的调用了. class OldboyPeople: school = 'oldboy' def __init__(self,name ...

  6. python对象调用父类的方法

    #类定义 class People: #定义基本属性 name = '' age = 0 #定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 #定义构造方法 def __ini ...

  7. java继承-子类调用父类的方法中包含子类重写的方法

    # 看题目是不是很绕,这个我也不知道怎么才能更简单的表达了... # 先看代码: public class Common { public static void main(String[] args ...

  8. python 子类调用父类成员的方法

    1.直接写类名调用: parent_class.parent_attribute(self) class Animal(): def __init__(self, name): self.name = ...

  9. python 子类调用 父类的构造函数

    class A(object): def __init__(self): self.nameaa = 'aa' def funca(self): print('function a %s' % sel ...

随机推荐

  1. 关于CSS动画效果的图片展示

    animation:帧动画 animation-name:定义绑定Keyframes的动画名称 @keyframes XXX 定义动画,里面是动画具体内容 animation-duration:过渡动 ...

  2. AngularJS学习之模型

    1.ng-model指令:可以将输入域的值与AngularJS创建的变量绑定,用于绑定应用程序数据到HTML控制器(input,select,textarea)的值: <div ng-app=& ...

  3. 8、显示程序占用内存多少.txt

    方法一: 要加单元 PsAPI procedure TForm1.tmr1Timer(Sender: TObject); begin edt1.Text:= format('memory use: % ...

  4. NoSQL-Redis【2】-实现分布式Session

    经过一周紧张的开发和调试,终于把Redis实现的分布式Session发布到了生产环境.我在本地测试了100万的数据,Redis的速度确实让我满意,期待在线上有更好的表现. 一.配置windows-se ...

  5. JSP 中 pageEncoding 和 charset 区别以及中文乱码解决方案

    一.JSP 中 pageEndcodeing 和 charset 的作用 <%@ page contentType="text/html;charset=GB2312"%&g ...

  6. How to retrieve instance parameters from an uninstantiated (uninserted) family

    The trick to be able to read the default values for instance parameters is to get to the FamilyManag ...

  7. NHibernate 中删除数据的几种方法

    今天下午有人在QQ群上问在NHibernate上如何根据条件删除多条数据,于是我自己就写了些测试代码,并总结了一下NHibernate中删除数据的方式,做个备忘.不过不能保证囊括所有的方式,如果还有别 ...

  8. why cpp is a shitty language

    // the below is a standard template for any of my writings about c++ cpp_is_a_shitty_language_as { t ...

  9. XCODE UITextField 中的属性和用法

    XCODE  UITextField  中的属性和用法 一些基本的用法 UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedR ...

  10. ACM: Racing Gems - 最长递增序列

    Racing Gems   You are playing a racing game.  Your character starts at the x axis (y = 0) and procee ...