2009-07-29 10 views
4

クラス階層とコンストラクタは関連しています。子クラスのパラメータを親に渡す必要があります。Pythonでのコンストラクタの特殊化

だから、Pythonで、私たちはこのようなもので終わる:

class Parent(object): 
    def __init__(self, a, b, c, ka=None, kb=None, kc=None): 
     # do something with a, b, c, ka, kb, kc 

class Child(Parent): 
    def __init__(self, a, b, c, d, e, f, ka=None, kb=None, kc=None, kd=None, ke=None, kf=None): 
     super(Child, self).__init__(a, b, c, ka=ka, kb=kb, kc=kc) 
     # do something with d, e, f, kd, ke, kf 

はダースの子クラスとパラメータの多くでこれを想像してみてください。新しいパラメータを追加するのは非常に面倒です。

もちろん、名前付きパラメータを完全に省略して* argsと** kwargsを使用することができますが、メソッド宣言があいまいになります。

これをPython(2.6)でうまく処理するためのパターンはありますか?

「エレガントに」とは、パラメータが表示される回数を減らすことです。 a、b、c、ka、kb、kcは、子コンストラクタ内で、親にsuper()を呼び出し、親コンストラクタで3回現れます。

理想的には、私は親ののinit一度のパラメータを指定したいのですが、子供の中でINITのみで追加パラメータを指定します。

私はこのような何かをしたいと思います:

class Parent(object): 
    def __init__(self, a, b, c, ka=None, kb=None, kc=None): 
     print 'Parent: ', a, b, c, ka, kb, kc 

class Child(Parent): 
    def __init__(self, d, e, f, kd='d', ke='e', kf='f', *args, **kwargs): 
     super(Child, self).__init__(*args, **kwargs) 
     print 'Child: ', d, e, f, kd, ke, kf 

x = Child(1, 2, 3, 4, 5, 6, ka='a', kb='b', kc='c', kd='d', ke='e', kf='f') 

これは残念ながらKDに割り当てられた4、5、6エンドまで、KE、KF以来、動作しません。

上記を達成するためのエレガントなpythonパターンはありますか?

+0

どのように機能しますか?どういうわけか、私はより優雅さの可能性がどこに来るか見ていない。 –

答えて

6

「ダースの子クラスと多くのパラメータ」は、パラメータの名前付けに関係なく問題のように聞こえます。

少しのリファクタリングで、ストラテジーのオブジェクトがこの階層を単純化し、スーパーコンプレックスのコンストラクタを消滅させることがあると思われます。

+0

私は既にいくつかの戦略オブジェクトを取りまとめましたが、あなたのコメントは、完了しました。ありがとう! –

2

まあ、私はリストされた変数だけでなく、*引数と** kwargsからの混合物を使用している見ることができる唯一のソリューション、など:

class Parent(object): 
    def __init__(self, a, b, c, ka=None, kb=None, kc=None): 
     pass 

class Child(Parent): 
    def __init__(self, d, e, f, *args, kd=None, ke=None, kf=None, **kwargs): 
     Parent.__init__(self, *args, **kwargs) 
     pass 

この方法では、あなたがで必要とされるパラメータを見ることができました各クラスを再入力する必要はありません。

注意するべきことは、(d、e、f、a、b、c)になるように、あなたが望む順序(a、b、c、d、e、f)を失うことです。他の名前のないパラメーターの前に* argsを持つ方法があるかどうかはわかりません。

+0

それは私の最初の考えでもありましたが、Pythonは少なくとも2.6では* argsと** kwargsが最後になるように思えます。 –

+0

ええ、ええ。私はあなたがPython 3に移動したときのそれらの可能性の1つとしてそれをロックすると思います。 – Adam

1

私は例えば、自分のオブジェクトにパラメータグループにしようとは、代わりに sourceDirectory、たtargetdirectory、temporaryDirectory、serverNameの、するserverPortを渡すので、私は DirectoryContextとServerContextオブジェクトを持っていると思います。

の動作またはロジックがコンテキストオブジェクトから開始された場合は、hereに記載されているストラテジオブジェクトにつながる可能性があります。

関連する問題