8

mixinを使用してクラスにいくつかの機能を提供したいと考えています。この機能は、追加のオブジェクトごとの状態を使用します。このローカル状態を初期化する最もクリーンな方法は何だろうと思っていました。例を考えてみましょう:

class Mixin:
    items = []
    def append(self, x):
        self.items.append(x)
    def display(self):
        print self.items

class Foo(object, Mixin): pass
class Bar(object, Mixin): pass

foo = Foo()
foo.append('foo')
foo.display()

>>> ['foo']

bar = Bar()
bar.append('bar')
bar.display()

>>> ['foo', 'bar']

ここでは、状態はitemsリストです。Mixin本体で初期化するのは明らかに間違っています。通常、私はそれを で初期化します__init__が、Mixin をいじりたくありません__init__

私は次のことができます:

class Mixin:
    items = None

def append(self, x):
    if self.items is None:
        self.items = []
    self.items.append(x)

しかし、条件はそれぞれで評価されappend、最もクリーンなソリューションではないようです。

代替案はありますか?それとも、ミックスインに追加__init__するのが道ですか?

(ミックスインを使って良いかどうかは別問題)

関連

  • Mixins for Rubyでのインスタンス変数の初期化
4

2 に答える 2

4

__init__()それをMixinに入れることを提案します。デメリットは何だと思いますか?

class Mixin(object):
    def __init__(self, *args, **kwargs):
        super(Mixin, self).__init__(*args, **kwargs)
        self.items = []

これは正しい方法だと思います。他のすべての(おそらく機能する)ソリューションは、私にはハックのように見えます。

于 2013-05-24T09:14:51.500 に答える
0

最もクリーンな解決策は、メソッドを追加し、それらのメソッドのそれぞれで__init__使用super()して、すべてのメソッドが確実に呼び出されるようにすることです。

class Mixin:
    def __init__(self, *args, **kwargs):
        self.items = []
        super(Mixin, self).__init__(*args, **kwargs)
    def append(self, x):
        self.items.append(x)
    def display(self):
        print self.items
于 2013-05-24T09:14:04.123 に答える