python中的继承和重写init

2024-05-08 22:13:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我读过《潜入Python》,在关于类的章节中,它给出了一个例子:

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

作者接着说,如果要重写__init__方法,必须用正确的参数显式调用父方法__init__

  1. 如果这个FileInfo类有多个祖先类呢?
    • 我必须显式地调用所有祖先类__init__方法吗?
  2. 另外,我是否必须对要重写的任何其他方法执行此操作?

Tags: 方法storenameselfnoneinitdeffilename
3条回答

在需要继承的每个类中,可以在启动子类时运行需要初始化的每个类的循环…可以复制的示例可能更容易理解。。。

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

关于子类超类调用,这本书有点过时了。对于内置类的子类化来说,它也有点过时了。

现在看来:

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

注意以下几点:

  1. 我们可以直接对内置类进行子类划分,如dictlisttuple等。

  2. 函数super处理跟踪此类的超类并适当调用其中的函数。

您没有真正的调用基类的__init__方法,但通常希望这样做,因为基类将在那里进行一些重要的初始化,而其他类方法需要在那里工作。

其他方法则取决于你的意图。如果只想在基类行为中添加一些内容,则需要在自己的代码之外调用基类方法。如果要从根本上更改行为,则可能不会调用基类的方法并直接在派生类中实现所有功能。

相关问题 更多 >

    热门问题