Python-继承注意点

Python 继承防坑小记

Posted by Sylvia on January 29, 2018

今天想和大家谈一下小白在写python代码时,在继承中遇到的两个坑。
相信大家对于python的构造方法一定不陌生吧,在python中用__init__来对类进行初始化,如下例:

class City():
    def __init__(self):
        self.empty = True

    def build(self):
        if self.empty:
            print 'i need buildings'
            self.empty = False
        else:
            print 'plz do other things'

这个栗子中的__init__方法里定义了初始变量empty,并且通过build方法来切换empty的值。
下面我们来构造一个City的子类District:

class District(City):
      pass
      
>>>d = District()
>>>d.empty
True

现在这个空空荡荡的District类继承了父类City,当它被调用时,首先在自身寻找empty变量,当找不到时,则会去父类中找。我们希望为它定义一些初始变量,试一下:

class District(City):
    def __init__(self):
        self.vehicle = 'bicycles'
        
    def traffic(self):
        print self.vehicle

>>> d = District()
>>> d.traffic()
AttributeError: 'District' object has no attribute 'empty'

这是第一个坑,我们为District类创建初始化方法时,会将City类初始化方法中定义的empty变量覆盖。那么我们该如何解决该问题呢?
这里就要用到super函数:

class District(City):
    def __init__(self):
        self.vehicle = 'bicycles'
        super(District, self).__init__()

    def traffic(self):
        print self.vehicle

这样就能保证District类既能继承City方法的初始化变量,有可以使用自己的初始化变量。
以为问题都解决了?然鹅,并没有,我们来运行一下:

>>>d = District()
>>>d.traffic()
TypeError: must be type, not classobj

又是一个坑 T-T
查了资料后发现,python中的super只能应用于新类,而不能应用于经典类,而所谓新类就是所有类都必须要有继承的类。然鹅City并不需要继承于哪个类,怎么办呢?我们可以将它继承到object类,像这样:

class City(object):
    def __init__(self):
        self.empty = True

    def build(self):
        if self.empty:
            print 'i need buildings'
            self.empty = False
        else:
            print 'plz do other things'


class District(City):
    def __init__(self):
        self.vehicle = 'bicycles'
        super(District, self).__init__()

    def traffic(self):
        print self.vehicle


sb = District()
sb.traffic()

然后,一切都平静了…