diff --git a/examples/basic-pretty.json b/examples/basic-pretty.json new file mode 100644 index 0000000..6205966 --- /dev/null +++ b/examples/basic-pretty.json @@ -0,0 +1,11 @@ +{ + "published": true, + "tags": [ + "diveintopython", + "docbook", + "html" + ], + "comments_link": null, + "id": 256, + "title": "Dive into history, 2009 edition" +} \ No newline at end of file diff --git a/examples/basic.json b/examples/basic.json new file mode 100644 index 0000000..e250615 --- /dev/null +++ b/examples/basic.json @@ -0,0 +1 @@ +{"published": true, "tags": ["diveintopython", "docbook", "html"], "comments_link": null, "id": 256, "title": "Dive into history, 2009 edition"} \ No newline at end of file diff --git a/examples/entry-pretty.json b/examples/entry-pretty.json new file mode 100644 index 0000000..b2df840 --- /dev/null +++ b/examples/entry-pretty.json @@ -0,0 +1,24 @@ +{ + "comments_link": null, + "internal_id": { + "__class__": "bytes", + "__value__": [ + 222, + 213, + 180, + 248 + ] + }, + "title": "Dive into history, 2009 edition", + "tags": [ + "diveintopython", + "docbook", + "html" + ], + "article_link": "http://diveintomark.org/archives/2009/03/27/dive-into-history-2009-edition", + "published_date": { + "__class__": "time.asctime", + "__value__": "Fri Mar 27 22:20:42 2009" + }, + "published": true +} \ No newline at end of file diff --git a/serializing.html b/serializing.html index fb1c8cb..99e4687 100644 --- a/serializing.html +++ b/serializing.html @@ -53,7 +53,7 @@ body{counter-reset:h1 13}

If this isn’t enough for you, the pickle module is also extensible, as you’ll see later in this chapter. -

Saving to a File

+

Saving Data to a Pickle File

The pickle module works with data structures. Let’s build one. @@ -104,7 +104,7 @@ body{counter-reset:h1 13}

  • The latest version of the pickle protocol is a binary format. Be sure to open your pickle files in binary mode, or the data will get corrupted during writing. -

    Loading from a File

    +

    Loading Data from a Pickle File

    Now switch to your second Python Shell — i.e. not the one where you created the entry dictionary. @@ -313,9 +313,65 @@ def protocol_version(file_object):

    Third, there’s the perennial problem of character encoding. JSON encodes values as plain text, but as you know, there ain’t no such thing as “plain text.” JSON must be stored in a Unicode encoding (UTF-32, UTF-16, or the default, UTF-8), and section 3 of RFC 4627 defines how to tell which encoding is being used. +

    Saving Data to a JSON File

    + +

    JSON looks remarkably like a data structure you might define manually in JavaScript. This is no accident; you can actually use the JavaScript eval() function to “decode” JSON-serialized data. (The usual caveats about untrusted input apply, but the point is that JSON is valid JavaScript.) As such, JSON may already look familiar to you. + +

    +>>> shell
    +1
    +>>> basic_entry = {}                                           
    +>>> basic_entry['id'] = 256
    +>>> basic_entry['title'] = 'Dive into history, 2009 edition'
    +>>> basic_entry['tags'] = ('diveintopython', 'docbook', 'html')
    +>>> basic_entry['published'] = True
    +>>> basic_entry['comments_link'] = None
    +>>> import json
    +>>> with open('basic.json', mode='w', encoding='utf-8') as f:  
    +...     json.dump(basic_entry, f)                              
    +
      +
    1. We’re going to create a new data structure instead of re-using the existing entry data structure. Later in this chapter, we’ll see what happens when we try to encode the more complex data structure in JSON. +
    2. JSON is a text-based format, which means you need to open this file in text mode and specify a character encoding. You can never go wrong with UTF-8. +
    3. Like the pickle module, the json module defines a dump() function which takes a Python data structure and a writeable stream object. The dump() function serializes the Python data structure and writes it to the stream object. Doing this inside a with statement will ensure that the file is closed properly when we’re done. +
    + +

    So what does the resulting JSON serialization look like? + +

    +you@localhost:~/diveintopython3/examples$ cat basic.json
    +{"published": true, "tags": ["diveintopython", "docbook", "html"], "comments_link": null,
    +"id": 256, "title": "Dive into history, 2009 edition"}
    + +

    That’s certainly more readable than a pickle file. But JSON can contain arbitrary whitespace between values, and the json module provides an easy way to take advantage of this to create even more readable JSON files. + +

    +>>> shell
    +1
    +>>> with open('basic-pretty.json', mode='w', encoding='utf-8') as f:
    +...     json.dump(basic_entry, f, indent=2)                    
    +
      +
    1. If you pass an indent parameter to the json.dump() function, it will make the resulting JSON file more readable, at the expense of larger file size. The indent parameter is an integer. 0 means “put each value on its own line.” A number greater than 0 means “put each value on its own line, and indent that many spaces.” +
    + +

    And this is the result: + +

    +you@localhost:~/diveintopython3/examples$ cat basic-pretty.json
    +{
    +  "published": true, 
    +  "tags": [
    +    "diveintopython", 
    +    "docbook", 
    +    "html"
    +  ], 
    +  "comments_link": null, 
    +  "id": 256, 
    +  "title": "Dive into history, 2009 edition"
    +}
    +

    Mapping of Python Datatypes to JSON

    -

    Since JSON is not Python-specific, there are some mismatches in its coverage of Python datatypes. Some of them are simply naming differences, but there is one important datatype that is completely missing. See if you can spot it: +

    Since JSON is not Python-specific, there are some mismatches in its coverage of Python datatypes. Some of them are simply naming differences, but there is two important Python datatypes that are completely missing. See if you can spot them:
    Notes @@ -336,18 +392,19 @@ def protocol_version(file_object):
    real number float -
    +
    * true True -
    +
    * false False -
    +
    * null None +
    * Remember that JSON values are case-sensitive.
    -

    Did you notice what was missing? Bytes! JSON has no support for bytes objects or byte arrays. +

    Did you notice what was missing? Tuples & bytes! JSON has an array type, which the json module maps to a Python list, but it does not have a separate type for “frozen arrays” (tuples). And while JSON supports strings quite nicely, it has no support for bytes objects or byte arrays.

    Serializing Datatypes Unsupported by JSON