ProgrammierungBackend-Entwickler

Erklären Sie, wie der eingebaute Mechanismus zur Serialisierung von Daten in Python (Module pickle und json) funktioniert. Was sind die Unterschiede, wofür werden sie verwendet und welche Gefahren birgt unvorsichtige Serialisierung?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

In Python werden zur Serialisierung (Umwandlung von Objekten in eine Bytefolge oder einen String zur Speicherung/Übertragung) die Module pickle und json verwendet:

  • pickle serialisiert beliebige Python-Objekte (sogar Klassen und Funktionen!), aber das Ergebnis ist eine binäre Folge. Funktioniert nur innerhalb des Python-Ökosystems.
  • json serialisiert nur einfache Datenstrukturen (dict, list, str, int, float), das Ergebnis ist jedoch ein String (universelles Format), das mit anderen Sprachen kompatibel ist.

Die Verwendung von Pickle zur Speicherung/Übertragung von Daten zwischen unkontrollierten Parteien ist riskant, da bei der Deserialisierung beliebiger schädlicher Code ausgeführt werden kann. json hat dieses Manko nicht.

Beispiel für die Verwendung:

import pickle import json # Pickle (binäre Serialisierung) data = {'x': 10, 'func': lambda x: x + 1} with open('data.pkl', 'wb') as f: pickle.dump(data, f) # JSON (nur einfache Objekte) data = {'x': 10, 'y': [1, 2, 3]} with open('data.json', 'w') as f: json.dump(data, f)

Fangfrage

Frage: Kann man pickle zur Serialisierung und Speicherung beliebiger Python-Objekte zwischen Sitzungen verwenden? Warum wird dieses Verfahren nicht empfohlen, um Benutzerdaten zu speichern?

Antwort:

Nein, pickle überall zu verwenden ist eine schlechte Praxis. Neben der Sicherheit (bei der Lade eines "fremden" pickled-Objekts kann die Ausführung kompromittiert werden) gibt es das Problem der Kompatibilität zwischen verschiedenen Python-Versionen oder Klassen - serialisierte Objekte können möglicherweise nicht geladen werden oder sich fehlerhaft verhalten, wenn sich die Struktur der Klassen geändert hat.

Beispiel:

# Laden einer pickle-Datei, die Struktur der Klasse hat sich geändert import pickle with open('old_version.pkl', 'rb') as f: obj = pickle.load(f) # AttributeError oder Strukturunterschiede

Geschichte

Beispiel 1

In einem großen Projekt wurde pickle zur Speicherung von Benutzerprofilen verwendet. Nach einem Update der Python-Version und einer Änderung der Klassen verlor die Struktur der serialisierten Objekte die Kompatibilität, was zu einem Systemausfall und dem Verlust der meisten Benutzerdaten führte.


Beispiel 2

In einem Webservice wurde pickle für die Benutzersitzungen verwendet. Ein böswilliger Akteur lud ein schädliches pickled-Objekt hoch, was es ermöglichte, Code-Injection auf dem Server durchzuführen.


Beispiel 3

Der Versuch, Funktionen über pickle zu serialisieren, um sie über das Netzwerk zu übertragen, scheiterte in mehreren Umgebungen: pickled-Lambdas können nicht zwischen Maschinen mit unterschiedlichen Konfigurationen/versionen von Python übertragen werden.