Change __slots__ dynamically

I am working on a class that needs to assign the __dict__ attribute using __init__ injection as follows:

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

And you need not change the structure of the object, because the instance will end in db NOSQL. I thought __slots__ might be useful, but I need to define it dynamically.

Is there a way to make this possible without a metaclass?

+3
source share
3 answers

Use the factory function:

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

Please note that to use the slots:

  • slots_iterable should be iterable from strings
  • Your class should be in a new style.
  • Your class cannot inherit a class that implements __dict__ (i.e. not just __slots__ )

Now you say that you do not need to change the structure of the object, using __slots__ not the only (and probably not the best) solution to your problem: using slots makes your class more difficult to use in code.

Instead, you can do the following:

 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)) 

This way you are sure that only your actual fields will be stored in your db.

+7
source

This should do the magic you require.

 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 aa print ab 
+2
source

__slots__ and __dict__ are usually alternatives. In any case, a metaclass will not help you dynamically create them for an instance, except that a custom metaclass can reduce the constraint when assigning to __dict__ (Django already does this).

0
source

All Articles