json --- کدگذار و کدگشای JSON¶
کد منبع: Lib/json/__init__.py
JSON (JavaScript Object Notation)، که توسط RFC 7159 (که RFC 4627 را منسوخ میکند) و ECMA-404 مشخص شده است، قالبی سبک برای تبادل داده است که از سینتکس لفظی شیء در JavaScript الهام گرفته است (اگرچه زیرمجموعهای دقیق از جاوااسکریپت نیست [1]).
توجه
اصطلاح «شیء» در زمینهی پردازش JSON در پایتون ممکن است مبهم باشد. همهی مقدارها در پایتون شیء هستند. در JSON، یک شیء به هر دادهای اشاره دارد که در آکولادها قرار گرفته باشد، مشابه یک دیکشنری پایتون.
هشدار
هنگام تجزیه دادههای JSON از منابع نامطمئن، احتیاط کنید. یک رشته JSON مخرب ممکن است باعث شود کدگشا منابع زیادی از CPU و حافظه را مصرف کند. توصیه میشود اندازه دادههایی که تجزیه میشوند محدود شود.
این ماژول یک API آشنا برای کاربران ماژولهای marshal و pickle کتابخانهی استاندارد را در اختیار قرار میدهد.
کدگذاری سلسلهمراتب اشیای پایهی پایتون:
>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print(json.dumps("\"foo\bar"))
"\"foo\bar"
>>> print(json.dumps('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'
کدگذاری فشرده:
>>> import json
>>> json.dumps([1, 2, 3, {'4': 5, '6': 7}], separators=(',', ':'))
'[1,2,3,{"4":5,"6":7}]'
چاپ خوانا:
>>> import json
>>> print(json.dumps({'6': 7, '4': 5}, sort_keys=True, indent=4))
{
"4": 5,
"6": 7
}
سفارشیسازی کدگذاری شیء JSON:
>>> import json
>>> def custom_json(obj):
... if isinstance(obj, complex):
... return {'__complex__': True, 'real': obj.real, 'imag': obj.imag}
... raise TypeError(f'Cannot serialize object of {type(obj)}')
...
>>> json.dumps(1 + 2j, default=custom_json)
'{"__complex__": true, "real": 1.0, "imag": 2.0}'
کدگشایی JSON:
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['streaming API']
سفارشیسازی کدگشایی شیء JSON:
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
... object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')
گسترش JSONEncoder:
>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
... def default(self, obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... # Let the base class default method raise the TypeError
... return super().default(obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[2.0', ', 1.0', ']']
استفاده از json در پوسته برای اعتبارسنجی و زیبانویسی:
$ echo '{"json":"obj"}' | python -m json
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -m json
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
برای مستندات تفصیلی، رابط خط فرمان را ببینید.
توجه
JSON زیرمجموعهای از YAML 1.2 است. JSON حاصل از تنظیمات پیشفرض این ماژول (بهویژه مقدار پیشفرض separators) نیز زیرمجموعهای از YAML 1.0 و 1.1 است. بنابراین، میتوان از این ماژول بهعنوان سریالساز (serializer) برای YAML نیز استفاده کرد.
توجه
کدگذارها و کدگشاهای این ماژول بهطور پیشفرض ترتیب ورودی و خروجی را حفظ میکنند. ترتیب تنها در صورتی از دست میرود که ظروف زیرین بدون ترتیب باشند.
استفادهی پایه¶
- json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)¶
obj را بهصورت یک جریان با قالب JSON، با استفاده از این جدول تبدیل پایتون به JSON، در fp (یک file-like object با پشتیبانی از
.write()) سریالسازی کنید.توجه
برخلاف
pickleوmarshal، JSON یک پروتکل قاببندیشده (framed protocol) نیست؛ بنابراین تلاش برای سریالسازی چندین شیء با فراخوانیهای مکررdump()با استفاده از همان fp منجر به یک پرونده JSON نامعتبر خواهد شد.- پارامترها:
obj (object) -- شیء پایتونی که باید سریالسازی شود.
fp (file-like object) -- شیء فایلماندی که obj به آن سریالسازی میشود. ماژول
jsonهمیشه اشیایstrتولید میکند، نه اشیایbytes؛ بنابراینfp.write()باید از ورودیstrپشتیبانی کند.skipkeys (bool) -- اگر
Trueباشد، کلیدهایی که از یک نوع پایه نیستند (str،int،float،bool،None) به جای پرتاب یکTypeErrorنادیده گرفته میشوند. پیشفرضFalse.ensure_ascii (bool) -- اگر
True(پیشفرض)، تضمین میشود که تمام نویسههای غیر ASCII و غیرقابلچاپ ورودی در خروجی خنثی شوند. اگرFalse، تمام نویسهها همانگونه که هستند در خروجی قرار میگیرند، به جز نویسههایی که باید خنثی شوند: علامت نقلقول، اسلش معکوس (reverse solidus)، و نویسههای کنترلی U+0000 تا U+001F.check_circular (bool) -- اگر
Falseباشد، بررسی ارجاعهای دوری برای انواع ظرفی نادیده گرفته میشود و یک ارجاع دوری بهRecursionError(یا بدتر) منجر خواهد شد. پیشفرضTrueاست.allow_nan (bool) -- اگر
Falseباشد، سریالسازی مقادیرfloatخارج از محدوده (nan،inf،-inf) با رعایت دقیق مشخصات JSON منجر بهValueErrorخواهد شد. اگرTrueباشد (پیشفرض)، معادلهای JavaScript آنها (NaN،Infinity،-Infinity) استفاده میشوند.cls (a
JSONEncodersubclass) -- در صورت تنظیم، یک کدگذار JSON سفارشی که متدdefault()آن بازنویسیشده، برای سریالسازی انواع داده سفارشی است. اگرNone(مقدار پیشفرض) باشد، ازJSONEncoderاستفاده میشود.indent (int | str | None) -- اگر یک عدد صحیح مثبت یا رشته باشد، عناصر آرایه JSON و اعضای شیء با آن سطح تورفتگی زیبانویسی میشوند. یک عدد صحیح مثبت باعث میشود هر سطح به همان تعداد فاصله تورفتگی پیدا کند؛ از یک رشته (مانند
"\t") برای تورفتگی هر سطح استفاده میشود. اگر صفر، منفی یا""(رشته خالی) باشد، فقط سطرهای جدید درج میشوند. اگرNone(پیشفرض) باشد، هیچ خط جدیدی درج نمیشود.separators (tuple | None) -- یک دو-تایی (two-tuple):
(item_separator, key_separator). اگرNoneباشد (حالت پیشفرض)، مقدار پیشفرض separators در صورتی برابر(', ', ': ')است که indent برابرNoneباشد، و در غیر این صورت برابر(',', ': ')است. برای فشردهترین JSON،(',', ':')را مشخص کنید تا فضای سفید حذف شود.default (callable | None) -- تابعی که برای اشیایی فراخوانی میشود که بهشکل دیگری نمیتوان آنها را سریالسازی کرد. این تابع باید نسخهای قابل کدگذاری بهصورت JSON از شیء را برگرداند یا یک
TypeErrorپرتاب کند. اگرNone(پیشفرض) باشد،TypeErrorپرتاب میشود.sort_keys (bool) -- اگر
Trueباشد، دیکشنریها بر اساس کلید مرتبشده خروجی داده میشوند. پیشفرضFalseاست.
تغییر یافته در نسخهی 3.2: پذیرش رشتهها برای indent علاوه بر اعداد صحیح.
تغییر یافته در نسخهی 3.4: اگر indent برابر
Noneنباشد، از(',', ': ')بهعنوان پیشفرض استفاده میشود.تغییر یافته در نسخهی 3.6: تمام پارامترهای اختیاری اکنون فقط کلیدواژهای هستند.
- json.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)¶
obj با استفاده از این جدول تبدیل به یک
strبا قالب JSON سریالسازی میشود. آرگومانها همان معنای خود درdump()را دارند.توجه
Keys in key/value pairs of JSON are always of the type
str. When a dictionary is converted into JSON, all the keys of the dictionary are coerced to strings. As a result of this, if a dictionary is converted into JSON and then back into a dictionary, the dictionary may not equal the original one. That is,loads(dumps(x)) != xif x has non-string keys. sort_keys sorts the keys before they are coerced to strings, so numeric keys are sorted by value, not by their string representation.
- json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶
fp را با استفاده از جدول تبدیل JSON به پایتون به یک شیء پایتون سریالزدایی کنید.
- پارامترها:
fp (file-like object) -- یک text file یا binary file که از
.read()پشتیبانی میکند و حاوی سند JSON برای سریالزدایی (deserialization) است.cls (a
JSONDecodersubclass) -- در صورت تنظیم، یک کدگشای JSON سفارشی است. آرگومانهای کلیدواژهای اضافی برایload()به سازندهی cls منتقل میشوند. اگرNone(پیشفرض) باشد، ازJSONDecoderاستفاده میشود.object_hook (callable | None) -- اگر تنظیم شود، تابعی است که با نتیجهی کدگشایی هر لفظی شیء JSON (یک
dict) فراخوانی میشود. مقدار بازگشتی این تابع بهجایdictاستفاده خواهد شد. از این قابلیت میتوان برای پیادهسازی کدگشاهای سفارشی استفاده کرد، برای مثال اشارهگذاری کلاس (class hinting) در JSON-RPC. پیشفرضNone.object_pairs_hook (callable | None) -- در صورت تنظیم، تابعی است که با نتیجهی کدگشایی هر شیء JSON بهصورت یک فهرست مرتب از جفتها فراخوانی میشود. مقدار بازگشتی این تابع بهجای
dictاستفاده خواهد شد. میتوان از این قابلیت برای پیادهسازی کدگشاهای سفارشی استفاده کرد. اگر object_hook نیز تنظیم شده باشد، object_pairs_hook اولویت دارد. پیشفرضNone.parse_float (callable | None) -- اگر تنظیمشده باشد، تابعی است که با رشتهی هر شناور JSON برای کدگشایی فراخوانی میشود. اگر
None(پیشفرض) باشد، معادلfloat(num_str)است. این میتواند برای تجزیهی شناورهای JSON به انواع داده سفارشی استفاده شود، برای مثالdecimal.Decimal.parse_int (callable | None) -- اگر تنظیم شود، تابعی است که با رشتهی هر عدد صحیح JSON که باید کدگشایی شود، فراخوانی میشود. اگر
None(پیشفرض) باشد، معادلint(num_str)است. میتوان از این برای تجزیهی اعداد صحیح JSON به انواع داده سفارشی استفاده کرد، برای مثالfloat.parse_constant (callable | None) -- در صورت تنظیم، تابعی است که با یکی از رشتههای زیر فراخوانی میشود:
'-Infinity'،'Infinity'یا'NaN'. از این میتوان برای پرتاب استثنا در صورت برخورد با اعداد نامعتبر JSON استفاده کرد. پیشفرضNone.
- برانگیختن:
JSONDecodeError -- هنگامی که دادهای که از حالت سریالشده خارج میشود (deserialized)، سند JSON معتبری نباشد.
UnicodeDecodeError -- هنگامی که دادهای که سریالزدایی میشود شامل دادههای کدگذاریشده با UTF-8، UTF-16 یا UTF-32 نباشد.
تغییر یافته در نسخهی 3.1:
پارامتر اختیاری object_pairs_hook اضافه شد.
parse_constant دیگر برای 'null'، 'true' و 'false' فراخوانی نمیشود.
تغییر یافته در نسخهی 3.6:
تمام پارامترهای اختیاری اکنون فقط کلیدواژهای هستند.
fp اکنون میتواند یک پرونده دودویی باشد. کدگذاری ورودی باید UTF-8، UTF-16 یا UTF-32 باشد.
تغییر یافته در نسخهی 3.11: مقدار پیشفرض parse_int یعنی
int()اکنون حداکثر طول رشتهی عدد صحیح را از طریق محدودیت طول تبدیل رشتهی عدد صحیح مفسر محدود میکند تا به جلوگیری از حملات منع سرویس کمک کند.
- json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶
کاملاً مشابه
load()است، اما بهجای یک شیء شبهپرونده، s (نمونهای ازstr،bytesیاbytearrayکه حاوی یک سند JSON است) را با استفاده از این جدول تبدیل به یک شیء پایتون تبدیل (deserialize) میکند.تغییر یافته در نسخهی 3.6: s اکنون میتواند از نوع
bytesیاbytearrayباشد. کدگذاری ورودی باید UTF-8، UTF-16 یا UTF-32 باشد.تغییر یافته در نسخهی 3.9: آرگومان کلیدواژهای encoding حذف شده است.
کدگذارها و کدگشاها¶
- class json.JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)¶
کدگشای ساده JSON.
بهطور پیشفرض، تبدیلهای زیر را در کدگشایی انجام میدهد:
JSON
پایتون
شیء
dict
آرایه
فهرست
رشته
str
عدد (int)
int
عدد (حقیقی)
float
true
True
false
False
null
None
همچنین
NaN،Infinityو-Infinityرا بهعنوان مقادیرfloatمتناظرشان میشناسد، که خارج از مشخصات JSON است.object_hook تابعی اختیاری است که با نتیجهی کدگشایی هر شیء JSON فراخوانی میشود و مقدار بازگشتی آن بهجای
dictدادهشده استفاده میشود. میتوان از آن برای فراهمکردن سریالزدایی سفارشی، برای نمونه برای پشتیبانی از اشارهگذاری کلاس (class hinting) در JSON-RPC، استفاده کرد.object_pairs_hook یک تابع اختیاری است که با نتیجهی کدگشایی هر شیء JSON بهصورت یک فهرست مرتب از جفتها فراخوانی میشود. مقدار بازگشتی object_pairs_hook بهجای
dictاستفاده خواهد شد. از این قابلیت میتوان برای پیادهسازی کدگشاهای سفارشی استفاده کرد. اگر object_hook نیز تعریف شده باشد، object_pairs_hook اولویت دارد.تغییر یافته در نسخهی 3.1: پشتیبانی از object_pairs_hook افزوده شد.
parse_float یک تابع اختیاری است که با رشتهی هر عدد اعشاری JSON که کدگشایی میشود، فراخوانی خواهد شد. بهطور پیشفرض، این معادل
float(num_str)است. میتوان از آن برای استفاده از یک نوع داده یا پارسر دیگر برای اعداد اعشاری JSON استفاده کرد (برای مثالdecimal.Decimal).parse_int تابعی اختیاری است که با رشتهی هر عدد صحیح JSON که باید کدگشایی شود، فراخوانی میشود. بهطور پیشفرض، این معادل
int(num_str)است. این را میتوان برای استفاده از نوع داده یا پارسر دیگری برای اعداد صحیح JSON (برای مثالfloat) به کار برد.parse_constant یک تابع اختیاری است که با یکی از رشتههای زیر فراخوانی میشود:
'-Infinity'،'Infinity'،'NaN'. میتوان از این برای پرتاب استثنا در صورت مواجهه با اعداد JSON نامعتبر استفاده کرد.اگر strict نادرست باشد (
Trueپیشفرض است)، آنگاه نویسههای کنترلی در داخل رشتهها مجاز خواهند بود. نویسههای کنترلی در این زمینه، آنهایی هستند که کدهای نویسهشان در بازهی ۰--۳۱ قرار دارند، شامل'\t'(تب)،'\n'،'\r'و'\0'.اگر دادهای که در حال بازخوانی (deserialize) است، سند JSON معتبری نباشد، استثنای
JSONDecodeErrorپرتاب خواهد شد.تغییر یافته در نسخهی 3.6: اکنون همهی پارامترها فقط کلیدواژهای هستند.
- decode(s)¶
بازنمایی پایتونی s (یک نمونهی
strکه شامل یک سند JSON است) را برمیگرداند.اگر سند JSON دادهشده معتبر نباشد،
JSONDecodeErrorپرتاب میشود.
- raw_decode(s)¶
یک سند JSON را از s (یک
strکه با یک سند JSON آغاز میشود) کدگشایی کنید و یک تاپل دوتایی شامل بازنمایی پایتونی و اندیسی در s که سند در آن به پایان رسیده است را برگردانید.این را میتوان برای کدگشایی یک سند JSON از رشتهای که ممکن است در انتهای خود دادههای اضافی داشته باشد به کار برد.
- class json.JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)¶
کدگذار JSON توسعهپذیر برای ساختارهای داده پایتون.
بهطور پیشفرض از اشیاء و انواع زیر پشتیبانی میکند:
پایتون
JSON
dict
شیء
فهرست، تاپل
آرایه
str
رشته
int، float، Enumهای مشتقشده از int و float
عدد
True
true
False
false
None
null
تغییر یافته در نسخهی 3.4: پشتیبانی از کلاسهای Enum مشتقشده از int و float افزوده شد.
برای گسترش آن جهت شناسایی اشیاء دیگر، یک زیرکلاس بسازید و متد
default()را با متد دیگری پیادهسازی کنید که در صورت امکان یک شیء قابل سریالسازی برایoبرمیگرداند؛ در غیر این صورت باید پیادهسازی ابرکلاس را فراخوانی کند (تاTypeErrorپرتاب شود).اگر skipkeys نادرست (پیشفرض) باشد، هنگام تلاش برای کدگذاری کلیدهایی که
str،int،float،boolیاNoneنیستند، یکTypeErrorپرتاب میشود. اگر skipkeys درست باشد، چنین آیتمهایی بهسادگی نادیده گرفته میشوند.اگر ensure_ascii برابر true باشد (پیشفرض)، تضمین میشود که در خروجی تمام نویسههای ورودی غیر ASCII و غیرقابلچاپ خنثی شوند. اگر ensure_ascii برابر false باشد، همه نویسهها همانطور که هستند در خروجی قرار میگیرند، به جز نویسههایی که باید خنثی شوند: علامت نقلقول، اسلش معکوس (reverse solidus)، و نویسههای کنترلی U+0000 تا U+001F.
اگر check_circular برابر true باشد (حالت پیشفرض)، فهرستها، دیکشنریها و اشیای کدگذاریشده سفارشی حین کدگذاری از نظر ارجاعهای دوری بررسی میشوند تا از یک بازگشت بیپایان (که باعث پرتاب
RecursionErrorمیشود) جلوگیری شود. در غیر این صورت، چنین بررسیای انجام نمیشود.اگر allow_nan مقدار true داشته باشد (پیشفرض)، آنگاه
NaN،Infinityو-Infinityبه همان صورت کدگذاری خواهند شد. این رفتار مطابق با مشخصات JSON نیست، اما با بیشتر کدگذارها و کدگشاهای مبتنی بر JavaScript سازگار است. در غیر این صورت، کدگذاری چنین اعداد اعشاریای موجبValueErrorخواهد شد.اگر sort_keys درست باشد (پیشفرض:
False)، خروجی دیکشنریها بر اساس کلید مرتب خواهد شد؛ این برای آزمونهای رگرسیون (regression tests) مفید است تا اطمینان حاصل شود که سریالسازیهای JSON را میتوان بهصورت روزمره مقایسه کرد.اگر indent یک عدد صحیح نامنفی یا رشته باشد، عناصر آرایه و اعضای شیء در JSON با آن سطح تورفتگی زیبانویسی میشوند. سطح تورفتگی ۰، منفی یا
""فقط سطرهای جدید را درج میکند.None(پیشفرض) فشردهترین نمایش را انتخاب میکند. استفاده از یک عدد صحیح مثبت بهعنوان تورفتگی، در هر سطح به همان تعداد فاصله درج میکند. اگر indent یک رشته باشد (مانند"\t")، از آن رشته برای تورفتگی هر سطح استفاده میشود.تغییر یافته در نسخهی 3.2: پذیرش رشتهها برای indent علاوه بر اعداد صحیح.
اگر مشخص شده باشد، separators باید یک تاپل
(item_separator, key_separator)باشد. اگر indent برابرNoneباشد، مقدار پیشفرض(', ', ': ')و در غیر این صورت(',', ': ')است. برای فشردهترین نمایش JSON، باید(',', ':')را مشخص کنید تا فضای سفید حذف شود.تغییر یافته در نسخهی 3.4: اگر indent برابر
Noneنباشد، از(',', ': ')بهعنوان پیشفرض استفاده میشود.اگر مشخص شده باشد، default باید تابعی باشد که برای اشیایی که نمیتوان آنها را به شکل دیگری سریالسازی کرد، فراخوانی میشود. این تابع باید نسخهای از شیء را برگرداند که قابل کدگذاری بهصورت JSON باشد یا
TypeErrorرا پرتاب کند. اگر مشخص نشده باشد،TypeErrorپرتاب میشود.تغییر یافته در نسخهی 3.6: اکنون همهی پارامترها فقط کلیدواژهای هستند.
- default(o)¶
این متد را در یک زیرکلاس بهگونهای پیادهسازی کنید که برای o یک شیء قابل سریالسازی برگرداند، یا پیادهسازی پایه را فراخوانی کند (تا
TypeErrorپرتاب شود).برای مثال، برای پشتیبانی از پیمایشگرهای دلخواه، میتوانید
default()را به این شکل پیادهسازی کنید:def default(self, o): try: iterable = iter(o) except TypeError: pass else: return list(iterable) # Let the base class default method raise the TypeError return super().default(o)
- encode(o)¶
یک نمایش رشتهای JSON از یک ساختار داده پایتون، o را برمیگرداند. برای مثال:
>>> json.JSONEncoder().encode({"foo": ["bar", "baz"]}) '{"foo": ["bar", "baz"]}'
- iterencode(o)¶
شیء دادهشده، o، را کدگذاری میکند و هر بازنمایی رشتهای را بهمحض در دسترس بودن تولید میکند. برای مثال:
for chunk in json.JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
استثناها¶
انطباق با استاندارد و تعاملپذیری¶
قالب JSON توسط RFC 7159 و ECMA-404 تعیین شده است. این بخش میزان انطباق این ماژول با RFC را با جزئیات شرح میدهد. برای سادگی، زیرکلاسهای JSONEncoder و JSONDecoder و پارامترهایی غیر از آنهایی که بهصراحت ذکر شدهاند، در نظر گرفته نمیشوند.
این ماژول بهصورت سختگیرانه با RFC مطابقت نمیکند و برخی افزونهها را پیادهسازی میکند که در JavaScript معتبر هستند اما در JSON معتبر نیستند. بهویژه:
مقادیر عددی بینهایت و NaN پذیرفته میشوند و در خروجی قرار میگیرند؛
نامهای تکراری در یک شیء پذیرفته میشوند و تنها از مقدار آخرین جفت نام-مقدار استفاده میشود.
از آنجایی که RFC به پارسرهای سازگار با RFC اجازه میدهد متنهای ورودیای را بپذیرند که با RFC سازگار نیستند، سریالزدا (deserializer) این ماژول از نظر فنی در تنظیمات پیشفرض با RFC سازگار است.
کدگذاریهای نویسه¶
RFC الزام میکند که JSON با استفاده از یکی از کدگذاریهای UTF-8، UTF-16 یا UTF-32 بازنمایی شود؛ UTF-8 بهعنوان پیشفرض توصیهشده برای حداکثر تعاملپذیری پیشنهاد میشود.
همانطور که توسط RFC مجاز است، هرچند الزامی نیست، سریالساز این ماژول بهطور پیشفرض ensure_ascii=True را تنظیم میکند، بدین ترتیب خروجی را خنثی میکند تا رشتههای حاصل فقط شامل نویسههای ASCII قابلچاپ باشند.
بهجز پارامتر ensure_ascii، این ماژول بهطور دقیق بر حسب تبدیل میان اشیای پایتون و رشتههای یونیکد تعریف شده است و بنابراین در غیر این صورت بهطور مستقیم به موضوع کدگذاریهای نویسه نمیپردازد.
این RFC افزودن نشانگر ترتیب بایت (BOM) به ابتدای یک متن JSON را ممنوع میکند و سریالساز این ماژول، یک BOM به خروجی خود اضافه نمیکند. این RFC به سریالزداهای JSON اجازه میدهد، اما آنها را ملزم نمیکند که یک BOM اولیه در ورودی خود را نادیده بگیرند. سریالزدای این ماژول، هنگام وجود یک BOM اولیه، یک ValueError پرتاب میکند.
RFC بهصراحت رشتههای JSON حاوی دنبالههای بایتی را که با نویسههای معتبر Unicode متناظر نیستند (مثلاً جانشینهای جفتنشده UTF-16) ممنوع نمیکند، اما تذکر میدهد که آنها ممکن است باعث مشکلات تعاملپذیری شوند. بهطور پیشفرض، این ماژول نقاط کد چنین دنبالههایی را میپذیرد و (در صورت وجود در str اصلی) خروجی میدهد.
مقادیر عددی بینهایت و NaN¶
این RFC اجازهی نمایش مقادیر عددی بینهایت یا NaN را نمیدهد. با وجود این، بهطور پیشفرض، این ماژول Infinity، -Infinity و NaN را میپذیرد و خروجی میدهد، گویی که مقادیر لفظی عددی معتبر JSON باشند:
>>> # Neither of these calls raises an exception, but the results are not valid JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # Same when deserializing
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan
در سریالساز (serializer)، میتوان از پارامتر allow_nan برای تغییر این رفتار استفاده کرد. در سریالزدا (deserializer)، میتوان از پارامتر parse_constant برای تغییر این رفتار استفاده کرد.
نامهای تکراری در یک شیء¶
RFC مشخص میکند که نامهای درون یک شیء JSON باید یکتا باشند، اما الزام نمیکند که با نامهای تکراری در اشیای JSON چگونه برخورد شود. بهطور پیشفرض، این ماژول استثنایی پرتاب نمیکند؛ در عوض، برای یک نام مشخص، همهی جفتهای نام-مقدار بهجز آخرین جفت را نادیده میگیرد:
>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{'x': 3}
میتوان از پارامتر object_pairs_hook برای تغییر این رفتار استفاده کرد.
مقادیر سطح بالا که نه شیء هستند و نه آرایه¶
نسخه قدیمی JSON که در RFC 4627 منسوخ مشخص شده بود، الزام میکرد که مقدار سطح بالای یک متن JSON باید یا یک شیء JSON یا یک آرایه (در پایتون dict یا list) باشد و نمیتوانست یک مقدار JSON از نوع null، بولی، عدد یا رشته باشد. RFC 7159 آن محدودیت را حذف کرد و این ماژول آن محدودیت را پیادهسازی نمیکند و هرگز نه در سریالساز (serializer) خود و نه در سریالزدا (deserializer) خود پیادهسازی نکرده است.
با این حال، برای حداکثر تعاملپذیری، ممکن است بخواهید خودتان داوطلبانه این محدودیت را رعایت کنید.
محدودیتهای پیادهسازی¶
برخی پیادهسازیهای JSON deserializer ممکن است محدودیتهایی برای موارد زیر تعیین کنند:
اندازهی متنهای JSON پذیرفتهشده
حداکثر سطح تودرتویی اشیاء و آرایههای JSON
بازه و دقت اعداد JSON
محتوا و حداکثر طول رشتههای JSON
این ماژول هیچگونه محدودیتی از این دست، فراتر از محدودیتهای خود انواع داده مرتبط پایتون یا خود مفسر پایتون، اعمال نمیکند.
هنگام سریالسازی به JSON، از هرگونه محدودیت از این دست در برنامههایی که ممکن است JSON شما را مصرف کنند آگاه باشید. بهویژه، رایج است که اعداد JSON به اعداد با دقت مضاعف IEEE 754 سریالزدایی شوند و بنابراین مشمول محدودیتهای بازه و دقت آن بازنمایی باشند. این موضوع بهویژه هنگام سریالسازی مقادیر int پایتون با بزرگی بسیار زیاد، یا هنگام سریالسازی نمونههایی از انواع عددی «نامتعارف» مانند decimal.Decimal اهمیت دارد.
رابط خط فرمان¶
کد منبع: Lib/json/tool.py
ماژول json را میتوان بهعنوان یک اسکریپت از طریق python -m json برای اعتبارسنجی و زیبانویسی اشیای JSON فراخوانی کرد. زیرماژول json.tool این رابط را پیادهسازی میکند.
اگر آرگومانهای اختیاری infile و outfile تعیین نشده باشند، بهترتیب از sys.stdin و sys.stdout استفاده خواهد شد:
$ echo '{"json": "obj"}' | python -m json
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -m json
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
تغییر یافته در نسخهی 3.5: خروجی اکنون به همان ترتیب ورودی است. برای مرتبسازی خروجی دیکشنریها بهترتیب الفبایی کلیدها، از گزینهی --sort-keys استفاده کنید.
تغییر یافته در نسخهی 3.14: ماژول json اکنون میتواند مستقیماً بهصورت python -m json اجرا شود. برای سازگاری با نسخههای پیشین، فراخوانی رابط خط فرمان بهصورت python -m json.tool همچنان پشتیبانی میشود.
گزینههای خط فرمان¶
- infile¶
پرونده JSON برای اعتبارسنجی یا زیبانویسی:
$ python -m json mp_films.json [ { "title": "And Now for Something Completely Different", "year": 1971 }, { "title": "Monty Python and the Holy Grail", "year": 1975 } ]
اگر infile مشخص نشده باشد، از
sys.stdinخوانده میشود.
- outfile¶
خروجی infile را در outfile دادهشده بنویسید. در غیر این صورت، آن را در
sys.stdoutبنویسید.
- --sort-keys¶
خروجی دیکشنریها را بر اساس کلید بهصورت الفبایی مرتب کنید.
اضافه شده در نسخهی 3.5.
- --no-ensure-ascii¶
غیرفعال کردن خنثیکردن نویسههای غیر ASCII، برای اطلاعات بیشتر
json.dumps()را ببینید.اضافه شده در نسخهی 3.9.
- --json-lines¶
هر خط ورودی را بهعنوان یک شیء JSON جداگانه تجزیه کنید.
اضافه شده در نسخهی 3.8.
- --indent, --tab, --no-indent, --compact¶
گزینههای متقابلاً انحصاری برای کنترل فضای سفید.
اضافه شده در نسخهی 3.9.
- -h, --help¶
نمایش پیام راهنما.
پانویسها