4

重複の可能性:
関数の引数を「self」に代入

多くの場合、次のようなコンストラクタがあります。

class Foo(object):
  def __init__(self,a,b,c):
    self.a = a
    self.b = b
    self.c = c

このようなコンストラクタをエンコードする便利な方法があるかどうか疑問に思っていました。おそらく次のようになります。

class Foo(object):
  SOME_MACRO_LIKE_THINGY_THAT_SPECIFIES_THE_CONSTRUCTOR(a,b,c)

上記の元のコードとまったく同じように動作します。

元のバージョンで私を悩ませているのは、Foo の各インスタンス変数を 3 回 (引数として 1 回、self.a として 1 回、self.a に割り当てる値として 2 回) 書き込まなければならないことです。

大したことではないと思いますが、繰り返しが少ないほどコードがきれいに見えると思います。

この状況を処理するPythonicの方法は何ですか?

4

3 に答える 3

2

Fooマスタークラスのサブクラスとして、その他すべてを作成できます。

class MasterObject(object):
  def __init__(self,a,b,c):
    self.a = a
    self.b = b
    self.c = c


class Foo(MasterObject):
  def __init__(self,a,b,c):
    MasterObject.__init__(a,b,c)
于 2012-11-19T22:28:59.583 に答える
2

奇妙ですが、__slots__これを達成するために使用できます:

class Base(object):
    def __init__(self, *args, **kw):
        for k,v in zip(self.__slots__, args):
            setattr(self, k, v)

        for k,v in kw.items():
            setattr(self, k, v)

class ChildA(Base):
    __slots__ = 'a', 'b', 'c'

class ChildB(Base):
    __slots__ = 'x', 'y', 'z'

次の手法を使用して、多くの引数を持つクラスを初期化するときに入力を節約することもできます。

def autoargs(l):
    self = l.pop('self')
    for k,v in l.items():
        setattr(self, k, v)

class Base(object):
    def __init__(self, a, b, c):
        autoargs(locals())

あなたの質問を正しく理解していることを願っています。

于 2012-11-19T22:35:02.243 に答える
0

あなたはこのようなことをすることができます

class Foo(object):
    def __init__(self, **kw):
        self.__dict__.update(kw)
        del self.__dict__["self"]

ただし、クラスをインスタンス化するたびに、すべてのインスタンス変数に名前を付ける必要があります。これにより、コードがより脆弱になると思います。ほとんどの人は脆弱なコードを好まないため、明示的なバージョンに固執します。

エディター用のマクロを作成してそれらを展開することもできますが、その詳細に非常に多くの時間が費やされているとは思いませんし、すべてのクラスがすべての引数をインスタンスに保存したいわけではありません。

于 2012-11-19T22:34:56.670 に答える