137

我正在阅读“潜入 Python”,并在关于类的章节中给出了这个例子:

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

然后作者说,如果要覆盖该方法,则必须使用正确的参数 __init__显式调用父级。__init__

  1. 如果FileInfo该类有多个祖先类怎么办?
    • 我必须显式调用所有祖先类的__init__方法吗?
  2. 另外,我是否必须对要覆盖的任何其他方法执行此操作?
4

5 回答 5

172

这本书在子类-超类调用方面有点过时了。关于子类化内置类也有点过时了。

现在看起来是这样的:

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

请注意以下事项:

  1. 我们可以直接子类化内置类,如dict, list,tuple等。

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

于 2009-04-15T20:49:52.597 回答
21

在您需要继承的每个类中,您可以在启动子类时运行每个需要初始化的类的循环......一个可以复制的示例可能会更好地理解......

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
于 2012-06-15T17:43:42.557 回答
16

您实际上不必调用__init__基类的方法,但您通常希望这样做,因为基类将在那里进行一些重要的初始化,这些初始化是其余类方法工作所需的。

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

于 2009-04-15T21:00:40.997 回答
4

如果 FileInfo 类有多个祖先类,那么您绝对应该调用它们的所有__init__()函数。您也应该对__del__()作为析构函数的函数执行相同的操作。

于 2009-04-15T20:49:08.247 回答
2

是的,您必须__init__为每个家长班级打电话。如果您要覆盖两个父项中都存在的函数,则函数也是如此。

于 2009-04-15T20:50:35.420 回答