Наследование и переопределение init в python
Я читал "погружение в Python" и в главе о классах он дает этот пример:
class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
затем автор говорит, что если вы хотите переопределить __init__ метод, вы должны явно вызвать родителей __init__ с правильными параметрами.
- , что если
FileInfoкласс имел более одного класса предков?
- должен ли я явно вызывать все классы предков'
__init__методами?
- должен ли я явно вызывать все классы предков'
- кроме того, я должен сделать это для любого другого метода, который я хочу переопределить?
5 ответов:
книга немного устарела в отношении подкласса-суперкласса вызова. Это также немного устарело в отношении встроенных классов подкласса.
это выглядит так в наши дни.
class FileInfo(dict): """store file metadata""" def __init__(self, filename=None): super( FileInfo, self ).__init__() self["name"] = filenameобратите внимание на следующее.
мы можем напрямую подкласс встроенных классов, как
dict,list,tupleи т. д.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