简体   繁体   English

python中的继承和覆盖__init__

[英]Inheritance and Overriding __init__ in python

I was reading 'Dive Into Python' and in the chapter on classes it gives this example:我正在阅读“深入 Python”,在关于类的章节中给出了这个例子:

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

The author then says that if you want to override the __init__ method, you must explicitly call the parent __init__ with the correct parameters.然后作者说,如果要覆盖__init__方法,则必须使用正确的参数显式调用父__init__方法。

  1. What if that FileInfo class had more than one ancestor class?如果FileInfo类有多个祖先类怎么办?
    • Do I have to explicitly call all of the ancestor classes' __init__ methods?我是否必须显式调用所有祖先类的__init__方法?
  2. Also, do I have to do this to any other method I want to override?另外,我是否必须对要覆盖的任何其他方法执行此操作?

The book is a bit dated with respect to subclass-superclass calling.这本书在子类-超类调用方面有点过时。 It's also a little dated with respect to subclassing built-in classes.它在子类化内置类方面也有点过时。

It looks like this nowadays:现在看起来是这样的:

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

Note the following:请注意以下事项:

  1. We can directly subclass built-in classes, like dict , list , tuple , etc.我们可以直接子类化内置类,如dictlisttuple等。

  2. The super function handles tracking down this class's superclasses and calling functions in them appropriately. super函数处理跟踪此类的超类并适当地调用其中的函数。

In each class that you need to inherit from, you can run a loop of each class that needs init'd upon initiation of the child class...an example that can copied might be better understood...在您需要继承的每个类中,您可以在子类启动时运行需要初始化的每个类的循环......可以复制的示例可能会更好地理解......

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

You don't really have to call the __init__ methods of the base class(es), but you usually want to do it because the base classes will do some important initializations there that are needed for rest of the classes methods to work.您实际上不必调用基类的__init__方法,但您通常要这样做,因为基类将在那里进行一些重要的初始化,这些初始化是其余类方法工作所需的。

For other methods it depends on your intentions.对于其他方法,这取决于您的意图。 If you just want to add something to the base classes behavior you will want to call the base classes method additionally to your own code.如果您只想向基类行为添加一些内容,您将需要在您自己的代码中额外调用基类方法。 If you want to fundamentally change the behavior, you might not call the base class' method and implement all the functionality directly in the derived class.如果您想从根本上改变行为,您可能不会调用基类的方法并直接在派生类中实现所有功能。

If the FileInfo class has more than one ancestor class then you should definitely call all of their __init__() functions.如果 FileInfo 类有多个祖先类,那么您绝对应该调用它们的所有 __init__() 函数。 You should also do the same for the __del__() function, which is a destructor.你也应该对 __del__() 函数做同样的事情,它是一个析构函数。

Yes, you must call __init__ for each parent class.是的,您必须为每个父类调用__init__ The same goes for functions, if you are overriding a function that exists in both parents.如果您要覆盖双亲中存在的函数,则函数也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM