Python og JSON er et naturligt par.
Uanset om du bygger et REST API med FastAPI
eller Django,
behandler datapipelines eller blot læser en konfigurationsfil — du vil arbejde med JSON konstant.
Den gode nyhed: Pythons standardbibliotek har alt, hvad du behøver, i
json-modulet.
Ingen pip install nødvendig.
De fire funktioner du faktisk bruger
Modulet json giver dig fire funktioner til det daglige arbejde:
json.loads(str)— parser en JSON-streng til et Python-objektjson.dumps(obj)— konverterer et Python-objekt til en JSON-strengjson.load(file)— parser JSON direkte fra et fil-objektjson.dump(obj, file)— skriver et Python-objekt som JSON til en fil
Bogstavet s i loads / dumps står for string (streng).
Dem uden s arbejder med filobjekter. Let at huske, når du kender reglen.
json.loads() — Parser en JSON-streng
import json
json_string = '{"name": "Alice", "age": 30, "active": true, "score": 98.5}'
user = json.loads(json_string)
print(user["name"]) # Alice
print(user["age"]) # 30
print(user["active"]) # True
print(type(user)) # <class 'dict'>Bemærk typemapping: JSON true bliver Python True,
JSON false bliver Python False, JSON null bliver Python None.
JSON-objekter bliver Python-dict, JSON-arrays bliver Python-list.
json.dumps() — Serialisering til en JSON-streng
import json
user = {
"name": "Bob",
"age": 25,
"roles": ["admin", "editor"],
"active": True,
"extra": None
}
# Kompakt (god til netværkstransmission)
compact = json.dumps(user)
print(compact)
# {"name": "Bob", "age": 25, "roles": ["admin", "editor"], "active": true, "extra": null}
# Pænt formateret (god til logs og menneskelig inspektion)
pretty = json.dumps(user, indent=2)
print(pretty)
# {
# "name": "Bob",
# "age": 25,
# "roles": [
# "admin",
# "editor"
# ],
# "active": true,
# "extra": null
# }Bemærk den omvendte typemapping: Python True → JSON true,
Python None → JSON null. Python håndterer dette automatisk.
Læsning af JSON fra en fil
Dette er sandsynligvis det mest almindelige brugstilfælde — læsning af en konfigurationsfil eller datafil ved opstart:
import json
# Læs og parser i ét trin
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print(config["database"]["host"]) # localhost
print(config["database"]["port"]) # 5432Angiv altid encoding="utf-8" når du åbner JSON-filer. JSON er specificeret som UTF-8
af RFC 8259,
og at udelade det kan forårsage problemer på Windows, hvor standardkodningen nogle gange er cp1252.
Skrivning af JSON til en fil
import json
results = {
"timestamp": "2024-01-15T09:30:00Z",
"total": 1523,
"processed": 1521,
"failed": 2,
"errors": [
{"id": 42, "reason": "missing field"},
{"id": 99, "reason": "invalid format"}
]
}
with open("results.json", "w", encoding="utf-8") as f:
json.dump(results, f, indent=2)
print("Results saved to results.json")Korrekt fejlhåndtering
json.loads() kaster
json.JSONDecodeError
(en underklasse til ValueError), når input ikke er gyldig JSON. Håndter altid dette, når du parser
data, du ikke kontrollerer:
import json
def safe_parse(json_str):
try:
return json.loads(json_str)
except json.JSONDecodeError as e:
print(f"Invalid JSON at line {e.lineno}, column {e.colno}: {e.msg}")
return None
data = safe_parse('{"name": "Alice"}') # fungerer fint
bad = safe_parse('not json at all') # udskriver fejl, returnerer None
also_bad = safe_parse('{"key": }') # udskriver fejl med positionsinfoJSONDecodeError giver dig den præcise linje og kolonne, hvor parsing mislykkedes —
nyttigt ved fejlsøgning af store JSON-filer.
Nyttige dumps()-indstillinger
import json
data = {
"z_key": 1,
"a_key": 2,
"price": 9.999999999
}
# Sorter nøgler alfabetisk (godt til reproducerbart output / diffs)
print(json.dumps(data, sort_keys=True, indent=2))
# {
# "a_key": 2,
# "price": 9.999999999,
# "z_key": 1
# }
# Bevar ikke-ASCII-tegn (standard: escaped til \uXXXX)
data2 = {"city": "Münich", "greeting": "こんにちは"}
print(json.dumps(data2, ensure_ascii=False))
# {"city": "Münich", "greeting": "こんにちは"}
# Med ensure_ascii=True (standard):
print(json.dumps(data2))
# {"city": "M\u00fcnich", "greeting": "\u3053\u3093\u306b\u3061\u306f"}ensure_ascii=False er noget, jeg altid tilføjer, når jeg skriver JSON-filer, der
indeholder ikke-ASCII-tekst. Den escapede version er teknisk set gyldig JSON, men meget sværere at
læse i en teksteditor.
Serialisering af brugerdefinerede objekter
Som standard kan json.dumps() ikke serialisere brugerdefinerede klasseinstanser eller
datetime-objekter.
Du har to muligheder: arv fra
json.JSONEncoder,
eller konverter til en dict først:
import json
from datetime import datetime, date
# Mulighed 1: brugerdefineret koderklasse
class AppEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
return super().default(obj)
data = {"name": "Alice", "created_at": datetime(2024, 1, 15, 9, 30)}
print(json.dumps(data, cls=AppEncoder, indent=2))
# {
# "name": "Alice",
# "created_at": "2024-01-15T09:30:00"
# }
# Mulighed 2: parameteren default= (enklere til engangkonverteringer)
print(json.dumps(data, default=str, indent=2)) # konverterer alt ukendt til strEt praktisk mønster: indlæsning af konfigurationsfil
Her er et virkeligt mønster, jeg bruger i næsten alle Python-projekter — en konfigurationsindlæser der læser en JSON-konfigfil med fornuftige standardværdier:
import json
import os
from pathlib import Path
DEFAULTS = {
"database": {"host": "localhost", "port": 5432},
"debug": False,
"log_level": "INFO"
}
def load_config(path="config.json"):
config = DEFAULTS.copy()
config_path = Path(path)
if config_path.exists():
with open(config_path, "r", encoding="utf-8") as f:
try:
user_config = json.load(f)
# Dyb sammenfletning: brugerindstillinger tilsidesætter standarder
for key, value in user_config.items():
if isinstance(value, dict) and key in config:
config[key].update(value)
else:
config[key] = value
except json.JSONDecodeError as e:
print(f"Warning: config.json is invalid ({e.msg}), using defaults")
return config
config = load_config()
print(config["database"]["host"]) # localhost (eller tilsidesat værdi)Opsummering
Pythons json-modul dækker alt, hvad du behøver, uden nogen afhængigheder.
Nøglereglerne: brug loads()/dumps() til strenge, load()/dump()
til filer, håndter altid JSONDecodeError ved parsing af eksterne data, og tilføj
ensure_ascii=False, når dine data indeholder ikke-latinske tegn.
Til fejlsøgning af JSON-data kan JSON Formatter og
JSON Validator spare dig meget tid.