3

次のように、インジェクション__dict__を介して属性を指定する必要があるクラスに取り組んでいます。__init__

class Torrent(Model):
    def __init__(self, d):
        super(Torrent, self).__init__('torrents')
        self.__dict__ = d

また、インスタンスが NOSQL データベースになるため、オブジェクトの構造を変更しないようにする必要があります。__slots__それは役立つと思いましたが、動的に定義する必要があります。

メタクラスなしでそれを可能にする方法はありますか?

4

3 に答える 3

8

ファクトリ関数を使用します。

def GetTorrentClass(slots_iterable):
    class Torrent(object):
        __slots__ = slots_iterable
    return Torrent

スロットを使用するには、次の点に注意してください。

  • slots_iterable文字列の iterable でなければなりません
  • あなたのクラスは新しいスタイルでなければなりません
  • あなたのクラスは、実装するクラスを継承できません__dict__(つまり、それ__slots__だけではありません)

ここで、「オブジェクトの構造を変更しないようにする必要がある」と言いますが、使用すること__slots__が問題の唯一の (そしておそらく最善ではない) 解決策ではありません。スロットを使用すると、クラスがコードで使用しにくくなります。

代わりに、次のことができます。

class Torrent(object):
    def __init__(self, fields):
        self.fields = fields #Fields could be ('field1', 'field2')

    def save(self):
        for field in self.fields:
            self.store_to_db(field, getattr(self, field))

このようにして、実際のフィールドのみがデータベースに保存されることが確実になります。

于 2012-05-30T18:41:51.803 に答える
3

これにより、必要な魔法が行われるはずです。

def construct_slots(slots):
    class SlotClass(object):
        __slots__ = slots
        def __init__(self, *args, **kwargs):
            for slot, arg in zip(SlotClass.__slots__, args):
                setattr(self, slot, arg)
            for key, value in kwargs:
                setattr(self, key, value)
    return SlotClass

Torrent = construct_slots(("a",'b','c'))
a = Torrent(1,2,3)
print a.a
print a.b
于 2012-05-30T18:42:05.210 に答える
0

__slots____dict__通常は代替手段です。どちらの場合も、カスタム メタクラスが割り当ての制限を緩和できることを除いて、メタクラスはインスタンスに対してそれらを動的に作成するのに役立ちません__dict__(Django は既にこれを行っています)。

于 2012-05-30T18:41:40.017 に答える