To JSON and Back Again
JavaScript Object Notation (JSON to its many friends) is a very useful string format for storing and retrieving complex data structures. Because pretty much every language provides tools for parsing and generating JSON strings, it’s also a handy way of sharing data between languages. You’re likely already familiar with PHP’s json_encode()
which takes a data structure and serialises it to a string and its equally handy sibling json_decode()
which converts a JSON string back into native data. As you’d expect, Python provides similar tools.
PHP Code Example:
Let’s build a simple array-based data structure and put it through a simple encode/decode round trip.
$business = [
"name" => "Happy Widgets",
"address" => [
"street" => "14 Jolly Way",
"city" => "Joyton"
]
];
$jsonstr = json_encode($business);
print gettype($jsonstr) . "\n";
print_r($jsonstr);
print "\n\n";
$decoded = json_decode($jsonstr, true);
print gettype($decoded) . "\n";
print_r($decoded);
So here we build a cut-down business entity (a flash of deja vu for me after years working on a large directory). We pass the multi-dimensional array to json_decode()
and print the result along with its type. Then we pass the encoded string to json_decode()
and convert it back into an array (note that second boolean argument which specifies that the function should return an array rather than a tree of objects). Finally we print the result and its type to demonstrate that we’ve come full circle.
Here’s the output:
string
{"name":"Happy Widgets","address":{"street":"14 Jolly Way","city":"Joyton"}}
array
Array
(
[name] => Happy Widgets
[address] => Array
(
[street] => 14 Jolly Way
[city] => Joyton
)
)
Python Code Example:
We will use a dictionary to construct a similar data structure and then walk it round the same encode and decode circuit.
business={
"name": "Happy Widgets",
"address": {
"street": "14 Jolly Way",
"city": "Joyton"
}
}
jsonstr = json.dumps(business)
print(type(jsonstr))
print(jsonstr)
print()
decoded = json.loads(jsonstr)
print(type(decoded))
print(decoded)
As you can see, the core functionality here is provided by the json
package. Although the output looks a little different, it demonstrates that we have converted the business
dictionary first into a JSON string, and then back into a dictionary.
<class 'str'>
{"name": "Happy Widgets", "address": {"street": "14 Jolly Way", "city": "Joyton"}}
<class 'dict'>
{'name': 'Happy Widgets', 'address': {'street': '14 Jolly Way', 'city': 'Joyton'}}
Discussion
So both PHP and Python bundle support for JSON. As usual, both examples perform exactly the same tasks. We create a data structure that defines a business with an address element. We pass this to a function that encodes it as JSON and we print the result. Then we complete the journey by decoding the JSON once again. We confirm the type of the reconstructed data and then print it.
In Python, you need to import the json
package. This provides tools for parsing and generating JSON strings and files.
So the json.dumps()
function generates a JSON string. The json
package also provides json.loads()
to acquire a data structure from a string. If the string is not well formed the call will result in an JSONDecodeError
, otherwise it will generate a Python object.
NOTE All keys in the data structure you wish to convert with
json.dumps()
orjson.dump()
should be of typestr
,int
,float
,bool
orNone
. These will be translated into strings in the JSON output. Values should be JSON serialisable.
By default, the PHP json_decode()
function will translate JSON objects into StdClass
objects rather than a multidimensional associative array. You can change that by passing true
as the optional second argument. json.loads()
will generate a dictionary when given a JSON object ({}
) to decode.
As they grow larger and more complex, JSON strings can be hard on the eyes. PHP lets you pretty print like this:
$prettyjson = json_encode($business, JSON_PRETTY_PRINT);
print $prettyjson . "\n";
You can pretty print in Python by setting the indent
parameter to the number of characters you would like to indent each level of the structure. This will also add newlines making for a nicely readable string. indent
is set to None
by default.
prettyjson = json.dumps(business, indent=4)
print(prettyjson)
The output for both these examples is identical.
{
"name": "Happy Widgets",
"address": {
"street": "14 Jolly Way",
"city": "Joyton"
}
}
If you want to write your JSON to a file from a Python script you could do it the PHP way and just print a pre-generated string. This is fine but can be expensive for a large data structure since you have to juggle a variable filled with data that you may not need in your script. Python’s json
package provides json.dump()
, a more direct way of getting the job done.
with open("outfiles/pybusiness2.json", "w") as dumpfile:
json.dump(business, dumpfile)
json.dump()
is identical to json.dumps()
except that it requires an object that supports write()
of the sort returned by open()
. Instead of returning a JSON string it writes the JSON to the given output. In this case it writes to the file outfiles/pybusiness2.json
.
As you might expect, you can also read from a JSON file with json.load()
:
with open("outfiles/pybusiness2.json", "r") as dumpfile:
readbusiness = json.load(dumpfile)
Further Reading:
Stay up to date with the Python for PHP Programmers project
Photo by Patrick Tomasso on Unsplash