Here is a simple solution for a simple feature:
.toJSON() Method
Instead of a JSON serializable class, implement a serializer method:
import json
class Object:
def toJSON(self):
return json.dumps(
self,
default=lambda o: o.__dict__,
sort_keys=True,
indent=4)
So you just call it to serialize:
me = Object()
me.name = "Onur"
me.age = 35
me.dog = Object()
me.dog.name = "Apollo"
print(me.toJSON())
will output:
{
"age": 35,
"dog": {
"name": "Apollo"
},
"name": "Onur"
}
For a fully-featured library, you can use orjson.
Answer from Onur Yıldırım on Stack OverflowHere is a simple solution for a simple feature:
.toJSON() Method
Instead of a JSON serializable class, implement a serializer method:
import json
class Object:
def toJSON(self):
return json.dumps(
self,
default=lambda o: o.__dict__,
sort_keys=True,
indent=4)
So you just call it to serialize:
me = Object()
me.name = "Onur"
me.age = 35
me.dog = Object()
me.dog.name = "Apollo"
print(me.toJSON())
will output:
{
"age": 35,
"dog": {
"name": "Apollo"
},
"name": "Onur"
}
For a fully-featured library, you can use orjson.
Do you have an idea about the expected output? For example, will this do?
>>> f = FileItem("/foo/bar")
>>> magic(f)
'{"fname": "/foo/bar"}'
In that case you can merely call json.dumps(f.__dict__).
If you want more customized output then you will have to subclass JSONEncoder and implement your own custom serialization.
For a trivial example, see below.
>>> from json import JSONEncoder
>>> class MyEncoder(JSONEncoder):
def default(self, o):
return o.__dict__
>>> MyEncoder().encode(f)
'{"fname": "/foo/bar"}'
Then you pass this class into the json.dumps() method as cls kwarg:
json.dumps(cls=MyEncoder)
If you also want to decode then you'll have to supply a custom object_hook to the JSONDecoder class. For example:
>>> def from_json(json_object):
if 'fname' in json_object:
return FileItem(json_object['fname'])
>>> f = JSONDecoder(object_hook = from_json).decode('{"fname": "/foo/bar"}')
>>> f
<__main__.FileItem object at 0x9337fac>
>>>
How can I make this class tree serializable with json?
python - Serializing class instance to JSON - Stack Overflow
My first Python library for converting class instances to JSON with a single decorator
How to convert JSON data into a Python object? - Stack Overflow
I'm trying to figure out how I can make this json serializable using the json library. I checked online and it looks like all object types must be set to a dictionary, so I set the functions up to cast to dict using dict. I get this error:
TypeError: Object of type builtin_function_or_method is not JSON serializable
Here's some sample code. The code I'm using is also using lists of classes, but I think the principle is the same. How can I cast a python class tree to a json string?
import json
class Child:
id: int
value: str
def __init__(self, id: int,value: str) -> None:
self.id = id
self.value = value
class Parent:
pid: int
child_obj: Child
def __init__(self, pid: int,child_obj: Child) -> None:
self.id = id
self.child_obj = child_obj
def BuildChild(id,value):
child = Child(id,value)
return child.__dict__
def BuildParent(child):
pid = "10"
parent = Parent(pid,child)
return parent.__dict__
def BuildJson():
child = BuildChild("4","SomeValue")
parent = BuildParent(child)
jstr = json.dumps(parent)
return jstr
jstr = BuildJson()
print(jstr)The basic problem is that the JSON encoder json.dumps() only knows how to serialize a limited set of object types by default, all built-in types. List here: https://docs.python.org/3.3/library/json.html#encoders-and-decoders
One good solution would be to make your class inherit from JSONEncoder and then implement the JSONEncoder.default() function, and make that function emit the correct JSON for your class.
A simple solution would be to call json.dumps() on the .__dict__ member of that instance. That is a standard Python dict and if your class is simple it will be JSON serializable.
class Foo(object):
def __init__(self):
self.x = 1
self.y = 2
foo = Foo()
s = json.dumps(foo) # raises TypeError with "is not JSON serializable"
s = json.dumps(foo.__dict__) # s set to: {"x":1, "y":2}
The above approach is discussed in this blog posting:
Serializing arbitrary Python objects to JSON using _dict_
And, of course, Python offers a built-in function that accesses .__dict__ for you, called vars().
So the above example can also be done as:
s = json.dumps(vars(foo)) # s set to: {"x":1, "y":2}
There's one way that works great for me that you can try out:
json.dumps() can take an optional parameter default where you can specify a custom serializer function for unknown types, which in my case looks like
def serialize(obj):
"""JSON serializer for objects not serializable by default json code"""
if isinstance(obj, date):
serial = obj.isoformat()
return serial
if isinstance(obj, time):
serial = obj.isoformat()
return serial
return obj.__dict__
First two ifs are for date and time serialization
and then there is a obj.__dict__ returned for any other object.
the final call looks like:
json.dumps(myObj, default=serialize)
It's especially good when you are serializing a collection and you don't want to call __dict__ explicitly for every object. Here it's done for you automatically.
So far worked so good for me, looking forward for your thoughts.
Hi there! My name's Avery and I've been working with Python for quite some time now. I've been recently working on a game for my girlfriend in Pygame for our 6th anniversary. While working on it I discovered that making a save system is quite troublesome, since I have to save all of the relevant data that is stored using class instances during the gameplay (I decided to use JSON as a save file format).
So that's why I decided to create my own first library that does exactly that, it's a single decorator that you put on a class that you wish to be converted to JSON along with all of its properties (and the nested properties of these properties and so on...)
Here's a short example from the README:
from jsonifable import Jsonifable
# it is not required to use dataclasses
# using them will just make this example shorter
from dataclasses import dataclass
@Jsonifable
@dataclass
class Person:
name: str
surname: str
person = Person("Avery", "Oliwa")
jsonified = person.to_json()
print(jsonified) # {"name": "Avery", "surname": "Oliwa"}I'm pretty proud of it, and any criticism is more than welcome!
Pypi: https://pypi.org/project/jsonifable/
GitHub: https://github.com/maciejoliwa/jsonifable
UPDATE
With Python3, you can do it in one line, using SimpleNamespace and object_hook:
import json
from types import SimpleNamespace
data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}'
# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(data, object_hook=lambda d: SimpleNamespace(**d))
# Or, in Python 3.13+:
# json.loads(data, object_hook=SimpleNamespace)
print(x.name, x.hometown.name, x.hometown.id)
OLD ANSWER (Python2)
In Python2, you can do it in one line, using namedtuple and object_hook (but it's very slow with many nested objects):
import json
from collections import namedtuple
data = '{"name": "John Smith", "hometown": {"name": "New York", "id": 123}}'
# Parse JSON into an object with attributes corresponding to dict keys.
x = json.loads(data, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))
print x.name, x.hometown.name, x.hometown.id
or, to reuse this easily:
def _json_object_hook(d): return namedtuple('X', d.keys())(*d.values())
def json2obj(data): return json.loads(data, object_hook=_json_object_hook)
x = json2obj(data)
If you want it to handle keys that aren't good attribute names, check out namedtuple's rename parameter.
You could try this:
class User():
def __init__(self, name, username):
self.name = name
self.username = username
import json
j = json.loads(your_json)
u = User(**j)
Just create a new object and pass the parameters as a map.
You can have a JSON with objects too:
import json
class Address():
def __init__(self, street, number):
self.street = street
self.number = number
def __str__(self):
return "{0} {1}".format(self.street, self.number)
class User():
def __init__(self, name, address):
self.name = name
self.address = Address(**address)
def __str__(self):
return "{0} ,{1}".format(self.name, self.address)
if __name__ == '__main__':
js = '''{"name":"Cristian", "address":{"street":"Sesame","number":122}}'''
j = json.loads(js)
print(j)
u = User(**j)
print(u)
I have never done this in python before but I'm pretty sure I could turn the retrieved JSON into a dictionary, but what is the best practice to convert the retrieved JSON into a class with its properties being items from the JSON.
So for example
{
"name":"Harry",
"job":"Mechanic"
}would yield
class Person:
def __init__(self, name, job):
self.name = name
self.job = jobAlso is there an easier way to do this.. something like a factory constructor.. ?