Python中使用json保存結構化數據--json是什麼?在python開發中的使用

內容簡介:JSON介紹,Python3標準庫中json模塊

拓展:Django中的JSONResponse()

一、JSON ?

JSON ( JavaScript Object Notation ) 是一種輕量級的數據交換語言,採用完全獨立於編程語言的文本格式來存儲和表示數 JavaScript對象文字語法的啓發 ,用於不同編程語言之間的數據交換。

看完上面之後,我們先來了解一下爲什麼要使用json ? 然後再一起去學習JSON中細節和Python語言中的json模塊。

爲何要使用json呢? 

JSON格式是現在流行的數據交換格式,因爲廣泛使用,所以用它來做數據交換是很好的選擇。假如我們用python語言開發的應用程序,需要將數據(字典或者嵌套列表)存儲在文件中或者發送給前端程序或者是通過網絡連接發送給某個遠程機器,這時候我們就要選用一個雙方統一約定出來的形式去表示python中複雜的數據類型,使其在其他的場景之下,這些數據對象能被直接保存或傳遞使用的,python中使用json保存結構化數據就要將我們的python對象轉換爲字符串表示形式,這個過程稱爲serializing(大都稱此過程爲序列化),然後作爲接收一方的時候,我們可以將獲得的這種格式字符串重建爲python對象,這個過程稱爲deserializing(反序列化)。

ps: 我們可以約定各種形式去完成這種數據交換,比如說,我們可以使用Python中的文件操作,但是我們都知道,字符串可以很輕鬆地寫入文件並讀取爲python中的字符串,數字的話,我們也可以讀取字符串(如‘123’)之後,然後通過int()將字符串類型轉變爲數字值123, 但是這種手工的操作對於複雜的數據類型是非常麻煩的,序列化和反序列化的過程會變得十分複雜。

 

JSON建構於兩種結構:

  • “名稱/值”對的集合(A collection of name/value pairs)。不同的語言中,它被理解爲對象(object),紀錄(record),結構(struct),字典(dictionary),哈希表(hash table),有鍵列表(keyed list),或者關聯數組 (associative array)。

  • 值的有序列表(An ordered list of values)。在大部分語言中,它被理解爲數組(array)。

本篇博文中的有關JSON的理解都來源於JSON介紹的官方網站,博文中關於JSON介紹的圖片的來源都出自這個網站。

         http://json.org

 

基於上面的兩種結構,json構建了自己的兩種表現形式:

 

 

                                                                                        自動機描述

object

對象是一個無序的“‘名稱/值’對”集合。

 

示例:{"name": "marsen", "age": 18}

   

array 

數組是值(value)的有序集合。

 

示例 :[ "marsen", 18 , {"id": "06", "score": 100} ]

 

 

上面結構中的value:值(value)可以是雙引號括起來的字符串(string)、數值(number)、true、false、 null、對象(object)或者數組(array)。

 

 

 

上面的自動機描述就是 JSON中的7種“基礎值”。下面表格給出其詳細描述:

   value類型

 

                                              自動機描述

    字符串    

  (string)

是由雙引號包圍的任意數量Unicode字符的集合,使用反斜線轉義。

     數值(number)

注意:JSON中的數值未使用八進制與十六進制格式

     對象(object)

 

   數組(array)

 

   true

 

 

  false

 

 

   null

 

 

 

JSON在線格式校驗:

http://www.bejson.com/

 

 


Python中如何使用json呢?

Python3標準庫中提供了一種方式-json模塊:官方API:https://docs.python.org/3/library/json.html

二、Python標準庫json模塊

在Python3的標準庫中有對JSON的支持---json模塊,這個模塊在Python 標準庫中定位是用來處理互聯數據的模塊之一,因爲我們在Web開發的過程中,前後端交互數據使用最多的還是json。

一、Python對象和JSON字符串之間的轉換  dumps和loads

二、JSON類型的數據文件與Python對象之間的轉換   dump和load

1、Python對象和JSON字符串之間的轉換  dumps和loads

(1)json.dumps : 將Python對象轉換爲JSON字符串(也就是具有JSON格式的字符串)

>>> import json
>>> json.dumps({'name':'marsen', 'age':18, 'like':['film','music',None]})

'{"name": "marsen", "age": 18, "like": ["film", "music", null]}'

這個函數提供很多可選參數,提供了各種功能:

json.dumps(obj*skipkeys=Falseensure_ascii=Truecheck_circular=Trueallow_nan=Truecls=Noneindent=Noneseparators=Nonedefault=Nonesort_keys=False**kw)

這個函數的官方說明:

def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
    """Serialize ``obj`` to a JSON formatted ``str``.

    If ``skipkeys`` is true then ``dict`` keys that are not basic types
    (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped
    instead of raising a ``TypeError``.

    If ``ensure_ascii`` is false, then the return value can contain non-ASCII
    characters if they appear in strings contained in ``obj``. Otherwise, all
    such characters are escaped in JSON strings.

    If ``check_circular`` is false, then the circular reference check
    for container types will be skipped and a circular reference will
    result in an ``OverflowError`` (or worse).

    If ``allow_nan`` is false, then it will be a ``ValueError`` to
    serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
    strict compliance of the JSON specification, instead of using the
    JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).

    If ``indent`` is a non-negative integer, then JSON array elements and
    object members will be pretty-printed with that indent level. An indent
    level of 0 will only insert newlines. ``None`` is the most compact
    representation.

    If specified, ``separators`` should be an ``(item_separator, key_separator)``
    tuple.  The default is ``(', ', ': ')`` if *indent* is ``None`` and
    ``(',', ': ')`` otherwise.  To get the most compact JSON representation,
    you should specify ``(',', ':')`` to eliminate whitespace.

    ``default(obj)`` is a function that should return a serializable version
    of obj or raise TypeError. The default simply raises TypeError.

    If *sort_keys* is true (default: ``False``), then the output of
    dictionaries will be sorted by key.

    To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
    ``.default()`` method to serialize additional types), specify it with
    the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.

    """

詳細說一下下面兩個關鍵字參數的使用:

1,indent這個關鍵字參數,我們可以用來將JSON字符串格式化顯示,如下所示:

>>> json.dumps({'name':'marsen', 'age':18, 'like':['film','music',None]}, indent=4)

'{\n    "name": "marsen",\n    "age": 18,\n    "like": [\n        "film",\n        "music",\n        null\n    ]\n}'
>>> print(json.dumps({'name': 'marsen', 'age': 18, 'like': ['film', 'music', None]}, indent=4))
{
    "name": "marsen",
    "age": 18,
    "like": [
        "film",
        "music",
        null
    ]
}

 

2,cls關鍵字參數的使用:它指明瞭“”編碼器‘’,如果使用json.dumps函數的時候沒有傳入這個關鍵字參數,那麼將使用“JSONEncoder”

json.JSONEncoder是json模塊帶有的類,定義了將Python數據結構轉換爲JSON數據結構,

Python----JSON
Python JSON
dict object
list, tuple array
str string
int, float,long number
True true
False flase
None null

 

(2)json.loads函數是將JSON字符串轉換爲Python對象

loads函數不只是能反序列化JSON字符串,也可以反序列化bytes或者是bytearray類型的“JSON數據”,要求是它們都“包含了JSON‘“”。

>>> json.loads('{"name": "marsen", "age": 18, "like": ["film", "music", null]}')
{'name': 'marsen', 'age': 18, 'like': ['film', 'music', None]}

函數的完整定義的說明文檔如下:

json.loads(s*encoding=Nonecls=Noneobject_hook=Noneparse_float=Noneparse_int=Noneparse_constant=Noneobject_pairs_hook=None**kw)

def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
    containing a JSON document) to a Python object.

    ``object_hook`` is an optional function that will be called with the
    result of any object literal decode (a ``dict``). The return value of
    ``object_hook`` will be used instead of the ``dict``. This feature
    can be used to implement custom decoders (e.g. JSON-RPC class hinting).

    ``object_pairs_hook`` is an optional function that will be called with the
    result of any object literal decoded with an ordered list of pairs.  The
    return value of ``object_pairs_hook`` will be used instead of the ``dict``.
    This feature can be used to implement custom decoders that rely on the
    order that the key and value pairs are decoded (for example,
    collections.OrderedDict will remember the order of insertion). If
    ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority.

    ``parse_float``, if specified, will be called with the string
    of every JSON float to be decoded. By default this is equivalent to
    float(num_str). This can be used to use another datatype or parser
    for JSON floats (e.g. decimal.Decimal).

    ``parse_int``, if specified, will be called with the string
    of every JSON int to be decoded. By default this is equivalent to
    int(num_str). This can be used to use another datatype or parser
    for JSON integers (e.g. float).

    ``parse_constant``, if specified, will be called with one of the
    following strings: -Infinity, Infinity, NaN.
    This can be used to raise an exception if invalid JSON numbers
    are encountered.

    To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
    kwarg; otherwise ``JSONDecoder`` is used.

    The ``encoding`` argument is ignored and deprecated.

    """

與dumps函數的參數定義對應的默認“解碼器”:JSONDecoder

json.JSONDecoder對應的轉換表:

JSON----PYTHON
JSON Python
object dict
array list
string str
number(int) int
number(real) float
true True
false False
null Null

 

拓展:在Django中的JSONResponse類,它的源碼就是使用了json.dumps函數對數據進行序列化,下面這段代碼是django1.11.11版本中的源碼:

class JsonResponse(HttpResponse):
    """
    An HTTP response class that consumes data to be serialized to JSON.

    :param data: Data to be dumped into json. By default only ``dict`` objects
      are allowed to be passed due to a security flaw before EcmaScript 5. See
      the ``safe`` parameter for more information.
    :param encoder: Should be an json encoder class. Defaults to
      ``django.core.serializers.json.DjangoJSONEncoder``.
    :param safe: Controls if only ``dict`` objects may be serialized. Defaults
      to ``True``.
    :param json_dumps_params: A dictionary of kwargs passed to json.dumps().
    """

    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                 json_dumps_params=None, **kwargs):
        if safe and not isinstance(data, dict):
            raise TypeError(
                'In order to allow non-dict objects to be serialized set the '
                'safe parameter to False.'
            )
        if json_dumps_params is None:
            json_dumps_params = {}
        kwargs.setdefault('content_type', 'application/json')
        data = json.dumps(data, cls=encoder, **json_dumps_params)
        super(JsonResponse, self).__init__(content=data, **kwargs)

 

2、JSON類型的數據文件與Python對象之間的轉換   dump和load

如果獲取了大量的JSON類型的數據,然後保存在了文件中,需要解析成Python數據,那麼使用load函數即可

with open('data.json', 'r') as f:
    data = json.load(f)

在Python中,如果我們想要將自己數據庫中查到的大量數據保存在文件中,並方便數據傳遞使用,那麼可以考慮將數據轉換成JSON格式並保存在文件中。使用dump函數

with open('data.json', 'w') as f:
    json.dump(data, f)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章