多くの___init__
_引数を持つ基本クラスがあります。
_def BaseClass(object):
def __init__(self, a, b, c, d, e, f, ...):
self._a=a+b
self._b=b if b else a
...
_
すべての継承クラスは、基本クラスの___init__
_メソッドを実行する必要があります。
スーパークラス___init__
_を呼び出す継承クラスのそれぞれに__init__()
メソッドを記述できますが、これは深刻なコードの重複になります。
_def A(BaseClass):
def __init__(self, a, b, c, d, e, f, ...):
super(A, self).__init__(a, b, c, d, e, f, ...)
def B(BaseClass):
def __init__(self, a, b, c, d, e, f, ...):
super(A, self).__init__(a, b, c, d, e, f, ...)
def C(BaseClass):
def __init__(self, a, b, c, d, e, f, ...):
super(A, self).__init__(a, b, c, d, e, f, ...)
...
_
スーパークラス___init__
_を自動的に呼び出す最もPython的な方法は何ですか?
super(SubClass, self).__init__(...)
変数の悪夢の解決に役立つ場合は、* argsと** kwの使用を検討してください。
明示的に記述する必要がありますが、一方で、多くの引数がある場合は、おそらく位置引数には* argsを、キーワード引数には** kwargsを使用する必要があります。
class SubClass(BaseClass):
def __init__(self, *args, **kwargs):
super(SubClass, self).__init__(*args, **kwargs)
# SubClass initialization code
使用できる別の手法は、initのコードを最小化し、init関数の最後に別のカスタム関数を呼び出すことです。次に、サブクラスで、カスタム関数をオーバーライドするだけです
class BaseClass(object):
def __init__(self, *args, **kwargs):
# initialization code
self._a = kwargs.get('a')
...
# custom code for subclass to override
self.load()
def load():
pass
class SubClass(BaseClass)
def load():
# SubClass initialization code
...
派生クラスが基本クラス__init__()
が既に行うことを超えて実装しない場合、派生クラス__init__()
メソッドを省略します-基本クラス__init__()
は自動的に呼び出されます。
OTOHで、派生クラスが__init__()
に余分な作業を追加し、基本クラス__init__()
を明示的に呼び出さないようにするには、次のようにします。
_class BaseClass(object):
def __new__(cls, a, b, c, d, e, f, ...):
new = object.__new__(cls)
new._a=a+b
new._b=b if b else a
...
return new
class A(BaseClass):
''' no __init__() at all here '''
class B(BaseClass):
def __init__(self, a, b, c, d, e, f, ...):
''' do stuff with init params specific to B objects '''
_
__new__()
は常に自動的に呼び出されるため、派生クラスでこれ以上の作業は必要ありません。
サブクラスの__init__()
メソッドで何か便利なことをしているのでなければ、オーバーライドする必要はありません。
def BaseClass(object):
def __init__(self, a, b, c, d, e, f, ...):
self._a=a+b
self._b=b if b else a
...
def A(BaseClass):
def some_other_method(self):
pass
def B(BaseClass):
pass
おそらくあなたの場合のより明確な実装は、次のように派生クラスで** kwargs 新しい追加の引数と組み合わせてを使用することです:
class Parent:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
class Child(Parent):
def __init__(self, d, **kwargs):
super(Child, self).__init__(**kwargs)
self.d = d
この方法により、コードの重複は避けられますが、派生クラスに暗黙的に引数が追加されます。
基本クラスからinitを継承する2.6以前のバージョンでは、スーパー関数はありません。以下の方法で継承できます。
class NewClass():
def __init__():
BaseClass.__init__(self, *args)
Pythonic実装を追加します。すべての属性を渡す必要がある場合、以下のコードを使用できます。 (サブセットが必要な場合は、特定のkwargsキーを保持/削除することもできます)。
def A(BaseClass):
def __init__(self, *args, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
base = BaseClass(...)
new = A( **base.__dict__ )