0

dict の機能を拡張するクラスを作成したいと考えています。これまでの私のコードは次のとおりです。

class Masks(dict):

    def __init__(self, positive=[], negative=[]):
        self['positive'] = positive
        self['negative'] = negative

コンストラクターに 2 つの事前定義された引数が必要です: ポジティブ マスクとネガティブ マスクのリストです。次のコードを実行すると、実行できます

m = Masks()

新しい mask-dictionary オブジェクトが作成されます - これで問題ありません。しかし、辞書でできるように、このマスクオブジェクトを作成できるようにしたいと思います:

d = dict(one=1, two=2)

しかし、これはマスクで失敗します:

>>> n = Masks(one=1, two=2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'two'

親コンストラクターinitをマスクのどこかで呼び出す必要があります。おそらく初期化します。親コンストラクターに渡して試してみました**kwargsが、それでも何か問題がありました。ここに何を追加すればよいか教えてもらえますか?

4

2 に答える 2

2

スーパークラスメソッドを呼び出す必要があります。そして、構文__init__を使用できるようにしたい場合は、次を使用する必要があります。Masks(one=1, ..)**kwargs

In [1]: class Masks(dict):
   ...:     def __init__(self, positive=(), negative=(), **kwargs):
   ...:         super(Masks, self).__init__(**kwargs)
   ...:         self['positive'] = list(positive)
   ...:         self['negative'] = list(negative)
   ...:         

In [2]: m = Masks(one=1, two=2)

In [3]: m['one']
Out[3]: 1

一般的な注意:ビルトインをサブクラス化しないでください!!! それらを拡張するのは簡単な方法のように思えますが、ある時点であなたを悩ませる落とし穴がたくさんあります.

ビルトインを拡張するより安全な方法は、委任を使用することです。これにより、サブクラスの動作をより適切に制御でき、ビルトインを継承する際の多くの落とし穴を回避できます。(実装__getattr__することで、明示的に多くのメソッドを再実装することを避けることができることに注意してください)

isinstance継承は、明示的なチェックを行うコードにオブジェクトを渡す場合の最後の手段として使用する必要があります。

于 2013-08-23T14:56:48.840 に答える
-1

必要なのは定義済みのエントリを持つ通常の dict だけなので、ファクトリ関数を使用できます。

def mask(*args, **kw):
    """Create mask dict using the same signature as dict(),
    defaulting 'positive' and 'negative' to empty lists.
    """
    d = dict(*args, **kw)
    d.setdefault('positive', [])
    d.setdefault('negative', [])
于 2013-08-23T15:08:23.847 に答える