Wat is in Python het verschil tussen json.load()
en json.loads()
?
Ik vermoed dat de functie load()moet worden gebruikt met een bestandsobject (ik moet dus een contextmanager gebruiken) terwijl de functie loads()de pad naar het bestand als een tekenreeks. Het is een beetje verwarrend.
Staat de letter “s” in json.loads()
voor string?
Hartelijk dank voor uw antwoorden!
Antwoord 1, autoriteit 100%
Ja, s
staat voor string. De functie json.loads
neemt niet het bestandspad, maar de bestandsinhoud als een tekenreeks. Bekijk de documentatie.
Antwoord 2, autoriteit 51%
Ik ga gewoon een eenvoudig voorbeeld toevoegen aan wat iedereen heeft uitgelegd,
json.load()
json.load
kan een bestand zelf deserialiseren, d.w.z. het accepteert een file
-object, bijvoorbeeld
# open a json file for reading and print content using json.load
with open("/xyz/json_data.json", "r") as content:
print(json.load(content))
uitvoert,
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}
Als ik json.loads
gebruik om in plaats daarvan een bestand te openen,
# you cannot use json.loads on file object
with open("json_data.json", "r") as content:
print(json.loads(content))
Ik krijg deze foutmelding:
TypeError: verwachte string of buffer
json.loads()
json.loads()
tekenreeks deserialiseren.
Dus om json.loads
te gebruiken, moet ik de inhoud van het bestand doorgeven met de functie read()
, bijvoorbeeld
gebruik content.read()
met json.loads()
retourneer de inhoud van het bestand,
with open("json_data.json", "r") as content:
print(json.loads(content.read()))
Uitvoer,
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}
Dat komt omdat het type content.read()
een tekenreeks is, d.w.z. <type 'str'>
Als ik json.load()
gebruik met content.read()
, krijg ik een foutmelding,
with open("json_data.json", "r") as content:
print(json.load(content.read()))
Geeft,
AttributeError: ‘str’ object heeft geen attribuut ‘read’
Dus nu weet je het json.load
deserialze-bestand en json.loads
deserialize een string.
Nog een voorbeeld,
sys.stdin
retourneer file
object, dus als ik print(json.load(sys.stdin))
doe, krijg ik werkelijke json-gegevens,
cat json_data.json | ./test.py
{u'event': {u'id': u'5206c7e2-da67-42da-9341-6ea403c632c7', u'name': u'Sufiyan Ghori'}}
Als ik json.loads()
wil gebruiken, zou ik in plaats daarvan print(json.loads(sys.stdin.read()))
doen.
Antwoord 3, autoriteit 15%
Documentatie is vrij duidelijk: https://docs.python.org/2/library /json.html
json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
Deserialiseer fp (een .read()-ondersteunend bestandsachtig object dat a . bevat
JSON-document) naar een Python-object met behulp van deze conversietabel.
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
Deserialiseer s (een str- of unicode-instantie die een JSON-document bevat)
naar een Python-object met behulp van deze conversietabel.
Dus load
is voor een bestand, loads
voor een string
Antwoord 4, autoriteit 9%
SNEL ANTWOORD (zeer vereenvoudigd!)
json.load() neemt een BESTAND
json.load() verwacht een bestand (bestandsobject) – b.v. een bestand dat je eerder hebt geopend, gegeven door bestandspad zoals
'files/example.json'
.
json.loads() duurt een STRING
json.loads() verwacht een (geldige) JSON-tekenreeks – bijv.
{"foo": "bar"}
VOORBEELDEN
Ervan uitgaande dat je een bestand example.jsonhebt met deze inhoud: { “key_1”: 1, “key_2”: “foo”, “Key_3”: null }
>>> import json
>>> file = open("example.json")
>>> type(file)
<class '_io.TextIOWrapper'>
>>> file
<_io.TextIOWrapper name='example.json' mode='r' encoding='UTF-8'>
>>> json.load(file)
{'key_1': 1, 'key_2': 'foo', 'Key_3': None}
>>> json.loads(file)
Traceback (most recent call last):
File "/usr/local/python/Versions/3.7/lib/python3.7/json/__init__.py", line 341, in loads
TypeError: the JSON object must be str, bytes or bytearray, not TextIOWrapper
>>> string = '{"foo": "bar"}'
>>> type(string)
<class 'str'>
>>> string
'{"foo": "bar"}'
>>> json.loads(string)
{'foo': 'bar'}
>>> json.load(string)
Traceback (most recent call last):
File "/usr/local/python/Versions/3.7/lib/python3.7/json/__init__.py", line 293, in load
return loads(fp.read(),
AttributeError: 'str' object has no attribute 'read'
Antwoord 5
In python3.7.7 is de definitie van json.load zoals hieronder volgens cpython-broncode:
def load(fp, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
return loads(fp.read(),
cls=cls, object_hook=object_hook,
parse_float=parse_float, parse_int=parse_int,
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
json.load roept eigenlijk json.loads aan en gebruikt fp.read()
als eerste argument.
Dus als uw code is:
with open (file) as fp:
s = fp.read()
json.loads(s)
Het is hetzelfde om dit te doen:
with open (file) as fp:
json.load(fp)
Maar als u de bytes wilt specificeren die uit het bestand worden gelezen, zoals fp.read(10)
of de string/bytes die u wilt deserialiseren niet uit het bestand komt, moet u json.loads gebruiken ()
Wat betreft json.loads(), het deserialiseert niet alleen string, maar ook bytes. Als s
bytes of bytearray is, wordt het eerst gedecodeerd naar string. Je kunt het ook vinden in de broncode.
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.
...
"""
if isinstance(s, str):
if s.startswith('\ufeff'):
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
s, 0)
else:
if not isinstance(s, (bytes, bytearray)):
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
f'not {s.__class__.__name__}')
s = s.decode(detect_encoding(s), 'surrogatepass')