Python中的继承与重载__init__

147 投票
6 回答
233958 浏览
提问于 2025-04-15 11:08

我在读《Dive Into Python》这本书,书中关于类的章节给了一个例子:

class FileInfo(UserDict):
    "store file metadata"
    def __init__(self, filename=None):
        UserDict.__init__(self)
        self["name"] = filename

作者接着说,如果你想要重写(也就是修改)__init__这个方法,你必须明确地调用父类的__init__,并且要传入正确的参数。

  1. 如果这个FileInfo类有多个父类,那我是不是就得把所有父类的__init__方法都调用一遍呢?
  2. 另外,我想重写其他方法的时候,也需要这样做吗?

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

注意以下几点:

  1. 我们可以直接继承一些内置类,比如 dict(字典)、list(列表)、tuple(元组)等。

  2. super 函数可以帮助我们找到这个类的父类,并且正确地调用它们里面的函数。

撰写回答