Python中的继承与重载__init__
我在读《Dive Into Python》这本书,书中关于类的章节给了一个例子:
class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
作者接着说,如果你想要重写(也就是修改)__init__
这个方法,你必须明确地调用父类的__init__
,并且要传入正确的参数。
- 如果这个
FileInfo
类有多个父类,那我是不是就得把所有父类的__init__
方法都调用一遍呢? - 另外,我想重写其他方法的时候,也需要这样做吗?
6 个回答
18
其实你并不一定要调用父类的__init__
方法,但通常你会想这样做,因为父类会在这个方法里做一些重要的初始化工作,这些工作是后面类的方法正常运行所需要的。
至于其他方法,是否调用父类的方法就要看你的目的了。如果你只是想在父类的基础上添加一些功能,那你就应该在自己的代码之外再调用一下父类的方法。如果你想彻底改变父类的行为,那你可能就不需要调用父类的方法,而是直接在子类里实现所有的功能。
22
在每个你需要继承的类里,你可以在子类初始化的时候,循环运行每个需要初始化的类。这样做可以让你更清楚地理解这个过程。下面是一个可以直接复制的例子...
class Female_Grandparent:
def __init__(self):
self.grandma_name = 'Grandma'
class Male_Grandparent:
def __init__(self):
self.grandpa_name = 'Grandpa'
class Parent(Female_Grandparent, Male_Grandparent):
def __init__(self):
Female_Grandparent.__init__(self)
Male_Grandparent.__init__(self)
self.parent_name = 'Parent Class'
class Child(Parent):
def __init__(self):
Parent.__init__(self)
#---------------------------------------------------------------------------------------#
for cls in Parent.__bases__: # This block grabs the classes of the child
cls.__init__(self) # class (which is named 'Parent' in this case),
# and iterates through them, initiating each one.
# The result is that each parent, of each child,
# is automatically handled upon initiation of the
# dependent class. WOOT WOOT! :D
#---------------------------------------------------------------------------------------#
g = Female_Grandparent()
print g.grandma_name
p = Parent()
print p.grandma_name
child = Child()
print child.grandma_name
177
这本书在讲解子类和父类之间的调用时有点过时了。关于如何继承内置类的内容也有些老旧。
现在的写法是这样的:
class FileInfo(dict):
"""store file metadata"""
def __init__(self, filename=None):
super(FileInfo, self).__init__()
self["name"] = filename
注意以下几点:
我们可以直接继承一些内置类,比如
dict
(字典)、list
(列表)、tuple
(元组)等。super
函数可以帮助我们找到这个类的父类,并且正确地调用它们里面的函数。