私は「Dive Into Python」を読んでいて、クラスの章でこの例を挙げています:
class FileInfo(UserDict):
"store file metadata"
def __init__(self, filename=None):
UserDict.__init__(self)
self["name"] = filename
その後、著者は、__init__
メソッドをオーバーライドする場合は、正しいパラメーターを使用して親__init__
を明示的に呼び出す必要があると言います。
FileInfo
クラスに複数の祖先クラスがあった場合はどうなりますか?__init__
メソッドを明示的に呼び出す必要がありますか?この本は、サブクラスとスーパークラスの呼び出しに関して少し古くなっています。また、サブクラスの組み込みクラスに関しては少し古いです。
最近はこんな感じです。
class FileInfo(dict):
"""store file metadata"""
def __init__(self, filename=None):
super( FileInfo, self ).__init__()
self["name"] = filename
以下に注意してください。
dict
、list
、Tuple
などの組み込みクラスを直接サブクラス化できます。
super
関数は、このクラスのスーパークラスを追跡し、それらの関数を適切に呼び出します。
継承する必要のある各クラスで、子クラスの開始時にinit'dを必要とする各クラスのループを実行できます...コピーできる例の方が理解しやすいかもしれません...
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__
メソッドを呼び出すのは実際にはhaveではありませんが、基本クラスが行うので通常はwantします残りのクラスメソッドが機能するために必要ないくつかの重要な初期化。
他の方法については、あなたの意図に依存します。基本クラスの動作に何かを追加するだけの場合は、独自のコードに追加して基本クラスメソッドを呼び出します。動作を根本的に変更する場合は、基本クラスのメソッドを呼び出して、派生クラスにすべての機能を直接実装しないでください。
FileInfoクラスに複数の祖先クラスがある場合、それらの__init __()関数をすべて呼び出す必要があります。デストラクタである__del __()関数についても同じことを行う必要があります。
はい、親クラスごとに__init__
を呼び出す必要があります。両方の親に存在する関数をオーバーライドする場合は、関数についても同じことが言えます。