Reputation: 750
I have defined two classes in Java. Let's call them 'User' and 'Address'
class Address {
String addressFirstLine;
String city;
String pincode;
// Getters/setters for all attributes
}
class User {
String firstName;
String lastName;
Address address;
// Getters/setters for all attributes
}
I created an object of class User and serialized it using Gson library.
The JSON String looks something like:
{"firstname":"Zen","lastName":"coder", "Address":{"addressFirstLine":"High st, Point place","city":"Wisconcin","pincode":"4E23C"}}
Now this string is sent to a python application which have the same two class definitions 'User' and 'Address' defined exactly like in Java above.
I have tried deserializing the json to a python object using jsonpickle. I can deserialize simple objects with jsonpickle but not complex objects.
Could anyone suggest a way around this?
Upvotes: 2
Views: 1480
Reputation: 5072
This may be a solution for you using Python built-in JSON library that takes advantage of Python's ability to ingest dictionaries as keyword arguments.
I defined the classes in Python as I would expect based on your outline. In the User class definition, I allow address to be passed as an actual address object, a list (converted from a JSON Array), or a dictionary (converted from a JSON object).
class Address(object):
def __init__(self, addressFirstLine, city, pincode):
self.addressFirstLine = addressFirstLine
self.city = city
self.pincode = pincode
class User(object):
def __init__(self, firstName, lastName, address):
self.firstName = firstName
self.lastName = lastName
if isinstance(address, Address):
self.address = address
elif isinstance(address, list):
self.address = Address(*address)
elif isinstance(address, dict):
self.address = Address(**address)
else:
raise TypeError('address must be provided as an Address object,'
' list, or dictionary')
I use the built-in Python json library to convert the JSON string you provided to a dictionary, then use that dictionary to create a user object. As you can see below, user.address is an actual Address object (I defined User and Address inside a file called user_address.py, hence the prefix).
>>> import json
>>> user_dict = json.loads('{
"firstName" : "Zen", "lastName" : "Coder",
"address" : {
"addressFirstLine" : "High st, Point place",
"city" : "Wisconcin",
"pincode" : "4E23C"}
}')
>>> from user_address import User
>>> user = User(**user_dict)
>>> user
<user_address.User at 0x1035b4190>
>>> user.firstName
u'Zen'
>>> user.lastName
u'coder'
>>> user.address
<user_address.Address at 0x1035b4710>
>>> user.address.addressFirstLine
u'High st, Point place'
>>> user.address.city
u'Wisconcin'
>>> user.address.pincode
u'4E23C'
This implementation also supports having a list of address arguments as opposed to a dictionary. It also raises a descriptive error if an unsupported type is passed.
>>> user_dict = json.loads('{
"firstName" : "Zen", "lastName" : "coder",
"address" : ["High st, Point place", "Wisconcin", "4E23C"]
}')
>>> user = User(**user_dict)
>>> user.address
<user_address.Address at 0x10ced2d10>
>>> user.address.city
u'Wisconcin'
>>> user_dict = json.loads('{
"firstName" : "Zen", "lastName" : "coder",
"address" : "bad address"
}')
TypeError: address must be provided as an Address object, list, or dictionary
This other answer also talks about converting a Python dict to a Python object, with a more abstract approach: Convert Python dict to object
Upvotes: 2