How can I do a normal conversion from an object to a dict?

I have a Python class that stores some fields and has some properties, like

class A(object): def __init__(self, x, y): self.x = x self.y = y @property def z(self): return self.x+1 

What changes do I need to make to the class so that I can do

 >>> a = A(1,5) >>> dict(a) {'y':5, 'z':2} 

where do I indicate that I want to return y and z ? I cannot just use a.__dict__ because it will contain x , but not z . I would like to be able to specify everything that can be accessed with __getattribute__ .

+4
source share
3 answers

Add the __iter__() method to your class, which returns an iterator of object objects as key-value pairs. You can then pass the instance of the object directly to the dict() constructor, since it takes a sequence of key-value pairs.

 def __iter__(self): for key in "y", "z": yield key, getattr(self, key) 

If you want this to be a little more flexible and make it easy to override the attribute list in subclasses (or programmatically), you could save the key list as an attribute of your class:

 _dictkeys = "y", "z" def __iter__(self): for key in self._dictkeys: yield key, getattr(self, key) 

If you want the dictionary to contain all the attributes (including those inherited from the parent classes), try:

 def __iter__(self): for key in dir(self): if not key.startswith("_"): value = getattr(self, key) if not callable(value): yield key, value 

This excludes participants that begin with "_", as well as called objects (such as classes and functions).

+11
source

I think a sensible approach to this problem would be to create an asdict method. When you say that you want to indicate which keys you want to contain a dict, I assume that you are happy with passing this information when the method is called. If this is not what you mean, let me know. (This includes a good-natured superb offer.)

 class A(object): def __init__(self, x, y): self.x = x self.y = y @property def z(self): return self.x+1 def asdict(self, *keys): if not keys: keys = ['y', 'z'] return dict((key, getattr(self, key)) for key in keys) 

Tested:

 >>> A(1, 2).asdict('x', 'y') {'y': 2, 'x': 1} >>> A(1, 2).asdict() {'y': 2, 'z': 2} 
+4
source

A naive way to solve this would be as follows. This may not be enough for your needs, but I just point it out if you missed it.

 >>> dict(y=ay, z=az) >>> {'y': 5, 'z': 2} 
0
source

Source: https://habr.com/ru/post/1416372/


All Articles