Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert python class with slots to dictionary?

I am using class with slots to reduce the memory which the instance will occupy. Now, how can I convert a slot instance to dictionary ?

The slot class look like this :

class Foo(object):
       __slots__ = ['x','y','z']
       def __init__(self):
           self.x = 1
           self.y = 2 
           self.z = 3

I expect something like this:

y = Foo()
y.__dict__
{'x': 1, 'y': 2, 'z': 3}
like image 263
Mero Avatar asked Feb 10 '14 16:02

Mero


People also ask

How do I turn a class into a dictionary in Python?

By using the __dict__ attribute on an object of a class and attaining the dictionary. All objects in Python have an attribute __dict__, which is a dictionary object containing all attributes defined for that object itself. The mapping of attributes with its values is done to generate a dictionary.

What is __ slots __ In Python class?

__slots__ is a class variable. If you have more than one instance of your class, any change made to __slots__ will show up in every instance. You cannot access the memory allocated by the __slots__ declaration by using subscription. You will get only what is currently stored in the list.

What is self __ dict __ Python?

__dict__ is A dictionary or other mapping object used to store an object's (writable) attributes. Or speaking in simple words every object in python has an attribute which is denoted by __dict__. And this object contains all attributes defined for the object.

How do Python slots work?

Slots in Python is a special mechanism that is used to reduce memory of the objects. In Python, all the objects use a dynamic dictionary for adding an attribute. Slots is a static type method in this no dynamic dictionary are required for allocating attribute.


2 Answers

Use the __slots__ attribute plus getattr() in a dictionary comprehension:

{s: getattr(obj, s) for s in obj.__slots__ if hasattr(obj, s)}

which skips any attributes not set.

Alternative, setting missing attributes to None:

{s: getattr(obj, s, None) for s in obj.__slots__}

Demo:

>>> class Foo(object):
...     __slots__ = ('bar', 'spam')
... 
>>> obj = Foo()
>>> obj.bar = 42
>>> {s: getattr(obj, s) for s in obj.__slots__ if hasattr(obj, s)}
{'bar': 42}
>>> {s: getattr(obj, s, None) for s in obj.__slots__}
{'spam': None, 'bar': 42}

You can even make that a property of the class and vars() will make use of it:

>>> class Foo(object):
...     __slots__ = ('bar', 'spam')
...     @property
...     def __dict__(self):
...         return {s: getattr(self, s) for s in self.__slots__ if hasattr(self, s)}
... 
>>> f = Foo()
>>> f.bar = 42
>>> f.__dict__
{'bar': 42}
>>> f.spam = 'eggs'
>>> f.__dict__
{'spam': 'eggs', 'bar': 42}
>>> vars(f)
{'spam': 'eggs', 'bar': 42}
>>> f.hello = 'world'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'hello'
like image 170
Martijn Pieters Avatar answered Nov 09 '22 04:11

Martijn Pieters


If you wanna read the props in slots, and store it into a dictionary, the dictionary comprehension through the property __slots__ is the way to go:

my_dict = {slot: getattr(obj, slot) for slot in obj.__slots__}
like image 20
bgusach Avatar answered Nov 09 '22 06:11

bgusach