2016-06-19 1 views
0

我々はBから継承したクラスAAとクラスCから継承するクラスBDEがあるとしましょう。フィールド

デフォルトの値で初期化された属性_fをすべて持っていて、その属性を変更可能にし、そのクラスのインスタンスごとに別の値を持たせたいとします。つまり、すべてのサブクラスによって使用されるAの一定値。これを行うには

一つの方法は、Aさん__init__方法で_fを定義し、サブクラスでこのメソッドに依存することです:

class A: 
    def __init__(self): 
     self._f = 'default_value' 

class B(A): 
    def __init__(self): 
     super(B, self).__init__() 

class C(B): 
    def __init__(self): 
     super(C, self).__init__() 

はこれを回避するために任意の素敵なPython的な方法はあります、そしておそらくメタクラスの使用を避けます?

+2

サブクラス実装がすべてスーパークラス実装を呼び出す場合は、それらをそのまま残すことができます。 'class B(A):pass'はうまくいくでしょう。 * class *属性またはregular * instance *属性を探していますか?抽象的な例はあまりありませんか? – jonrsharpe

+0

フィールド '_f 'が可変または不変型を参照する場合に依存します。 – Aya

+0

'_f'はクラスフィールドかインスタンスフィールドであるはずですか? – schwobaseggl

答えて

0

基本クラスのコンストラクタを呼び出す必要がなくなり、サブクラスのデフォルト値をオーバーライドできるようにすることで、サブクラスのコンストラクタを単純化することを目標にしている場合、Pythonがクラスの値を返すという共通のパラダイムがありますインスタンスに存在しない属性の場合もう少し具体的な例を使用して、代わりにやって

...

class Human(object): 

    def __init__(self): 
     self._fingers = 10 

    def __repr__(self): 
     return 'I am a %s with %d fingers' % (self.__class__.__name__, self._fingers) 


class MutatedHuman(Human): 

    def __init__(self, fingers): 
     super(MutatedHuman, self).__init__() 
     self._fingers = fingers 


print MutatedHuman(fingers=11) 
print Human() 

...あなたが使用することができます...

class Human(object): 

    _fingers = 10 

    def __repr__(self): 
     return 'I am a %s with %d fingers' % (self.__class__.__name__, self._fingers) 


class MutatedHuman(Human): 

    def __init__(self, fingers): 
     self._fingers = fingers 


print MutatedHuman(fingers=11) 
print Human() 

...どちらも出力の...

I am a MutatedHuman with 11 fingers 
I am a Human with 10 fingers 

重要な点は、実施例2における線self._fingers = fingersは、デフォルト値を上書きしないことであるSE tをクラスHumanに設定しますが、self._fingersと参照すると非表示になります。

変数がリストなどの変更可能な型を参照すると、やや毛むくじゃらします。 self.name = valueを実行することはまだ安全ですが、デフォルト値で操作を実行しないように注意する必要があります。

このアプローチでは、通常、Good Thing(tm)である他のアプローチよりもコード行の数が少なくなる傾向があります。