Czytałem „Dive Into Python” iw rozdziale poświęconym klasom podaje ten przykład:
class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
Następnie autor mówi, że jeśli chcesz przesłonić __init__
metodę, musisz jawnie wywołać rodzica __init__
z poprawnymi parametrami.
- A co by
FileInfo
było, gdyby ta klasa miała więcej niż jedną klasę przodków?- Czy muszę jawnie wywoływać wszystkie
__init__
metody klas nadrzędnych?
- Czy muszę jawnie wywoływać wszystkie
- Czy muszę to zrobić w innej metodzie, którą chcę zastąpić?
python
overriding
superclass
liewl
źródło
źródło
Odpowiedzi:
Książka jest nieco przestarzała w odniesieniu do wywołań podklasy i nadklasy. Jest też trochę przestarzały w odniesieniu do podklas wbudowanych w klasy.
Obecnie wygląda to tak:
class FileInfo(dict): """store file metadata""" def __init__(self, filename=None): super(FileInfo, self).__init__() self["name"] = filename
Zwróć uwagę na następujące kwestie:
Możemy bezpośrednio podklasy wbudowanych klas, jak
dict
,list
,tuple
, itd.Te
super
uchwyty funkcja śledzenia superklas tej klasy i wywołanie funkcji w nich odpowiednio.źródło
W każdej klasie, z której musisz dziedziczyć, możesz uruchomić pętlę każdej klasy, która wymaga zainicjowania po zainicjowaniu klasy podrzędnej ... przykład, który można skopiować, może być lepiej zrozumiany ...
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
źródło
Child.__init__
jest konieczna. Po usunięciu go z przykładu dziecko nadal drukuje napis „Babcia”. Czy dziadkowie nie są obsługiwani przezParent
klasę?Naprawdę nie musisz wywoływać
__init__
metod klas bazowych, ale zwykle chcesz to zrobić, ponieważ klasy podstawowe wykonają tam ważne inicjalizacje, które są potrzebne do działania pozostałych metod klas.W przypadku innych metod zależy to od Twoich intencji. Jeśli chcesz tylko dodać coś do zachowania klas bazowych, będziesz chciał wywołać metodę klas bazowych dodatkowo do własnego kodu. Jeśli chcesz zasadniczo zmienić zachowanie, możesz nie wywoływać metody klasy bazowej i zaimplementować wszystkich funkcji bezpośrednio w klasie pochodnej.
źródło
Jeśli klasa FileInfo ma więcej niż jedną klasę nadrzędną, zdecydowanie powinieneś wywołać wszystkie ich funkcje __init __ (). Powinieneś również zrobić to samo dla funkcji __del __ (), która jest destruktorem.
źródło
Tak, musisz wezwać
__init__
każdą klasę rodzicielską. To samo dotyczy funkcji, jeśli zastępujesz funkcję istniejącą u obojga rodziców.źródło