Наследование и переопределение init в 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. кроме того, я должен сделать это для любого другого метода, который я хочу переопределить?

722   5  

5 ответов:

книга немного устарела в отношении подкласса-суперкласса вызова. Это также немного устарело в отношении встроенных классов подкласса.

это выглядит так в наши дни.

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

обратите внимание на следующее.

  1. мы можем напрямую подкласс встроенных классов, как dict,list,tuple и т. д.

  2. The super функция обрабатывает отслеживание суперклассов этого класса и вызов функций в них соответственно.

в каждом классе, который вам нужно наследовать, вы можете запустить цикл каждого класса, который нуждается в инициализации при инициализации ребенка class...an пример, который можно скопировать, может быть лучше понят...

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

вы на самом деле не есть вызов __init__ методы базового класса (ов), но вы обычно хочу чтобы сделать это, потому что базовые классы будут делать некоторые важные инициализации там, которые необходимы для остальных методов классов для работы.

для других методов, это зависит от ваших намерений. Если вы просто хотите добавить что-то к поведению базовых классов, вам нужно будет вызвать метод базовых классов в дополнение к вашему собственному коду. Если вы хотите принципиально изменив поведение, можно не вызывать метод базового класса, а реализовать все функциональные возможности непосредственно в производном классе.

Если класс FileInfo имеет более одного класса предков, то вы обязательно должны вызвать все их функции __init__ (). Вы также должны сделать то же самое для функции __del__ (), которая является деструктором.

Да, вы должны позвонить __init__ для каждого родительского класса. То же самое касается функций, если вы переопределяете функцию, которая существует у обоих родителей.

Comments

    Ничего не найдено.