Problem: I have an instance of a class and I want to pass the main infos of the class to a json compatible format. I often resort to create a to_dict method like this:
class A:
def __init__(self, name, val):
self.name = name
self.val = val
def to_dict(self):
return {
'name': self.name,
'val': self.val,
}
Then i can do
a = A("a_name", 5)
a.to_dict()
which outputs {'name': 'a_name', 'val': 5}
However I think it is a bit inelegant. I considered modifying the __repr__
but I don't think it is better as I sometimes want a repr that is not a dict.
So my question: is there a better way to do this in python?
The Python standard library json
module's documentation says:
To extend this to recognize other objects, subclass and implement a default() method with another method that returns a serializable object for
o
if possible, otherwise it should call the superclass implementation (to raise TypeError ).
So you could do something like
from json import JSONEncoder
class MyJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, A):
return f'{{"name": "{o.name}", "value": {o.value}}}'
return super().default(o)
# ...
print(json.dumps(something, cls=MyJSONEncoder))
What I ended up doing to slightly generalize this was to say
def default(self, o):
if hasattr(o, '__json__'):
return o.__json__()
return super().default(o)
and then define a __json__
method in the classes I wanted to specify a JSON serialization format for.
There are several alternatives. For instance, you could make the instances iterable, and let that yield key/value pairs. Then use the dictionary constructor to take those key/value pairs:
class A:
def __init__(self, name, val):
self.name = name
self.val = val
def __iter__(self):
yield "name", self.name
yield "val", self.val
a = A("Helen", 42)
d = dict(a)
You can also use __dict__
,
from the example above:
class A:
def __init__(self, name, val):
self.name = name
self.val = val
a = A("Helen", 42)
print(a.__dict__)
# >>> {'name': 'Helen', 'val': 42}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.