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必须是字符串的可迭代
  • 你的课必须是新式的
  • 您的类不能继承实现的类__dict__(即__slots__不仅如此)

现在,您说您“需要确保不更改对象的结构”, using__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 回答