- Το JSON αντιστοιχίζεται καθαρά στους βασικούς τύπους της Python, με αντικείμενα και πίνακες να αναπαρίστανται ως dicts και lists, καθιστώντας την ανταλλαγή δεδομένων απλή.
- Η ενότητα json της Python παρέχει ευέλικτες συναρτήσεις dump/load με επιλογές για όμορφη εκτύπωση, προσαρμοσμένους κωδικοποιητές και σταθερή σειρά κλειδιών.
- Η ανάγνωση, η εγγραφή και η ανάλυση nested JSON από αρχεία και API βασίζονται στα ίδια βασικά εργαλεία, σε συνδυασμό με προσεκτικό χειρισμό σφαλμάτων.
- Πέρα από την βασική σειριοποίηση, το JSON σε Python υποστηρίζει μορφοποίηση, επικύρωση και ενσωμάτωση με άλλες μορφές δεδομένων όπως CSV και XML.
Η JSON έχει γίνει αθόρυβα η προεπιλεγμένη γλώσσα για δεδομένα στο διαδίκτυο, και αν γράφετε Python, τη συναντάτε παντού: API, αρχεία ρυθμίσεων, μικρές «βάσεις δεδομένων» για παράπλευρα έργα, αρχεία καταγραφής, ακόμη και δοκιμαστικά στοιχεία. Η κατανόηση του πώς οι τύποι δεδομένων της Python αντιστοιχίζονται σε JSON και πώς το json Το ότι η ενότητα λειτουργεί πραγματικά είναι μια από αυτές τις δεξιότητες που ξαφνικά κάνει πολλές καθημερινές εργασίες απλούστερες.
Αυτός ο οδηγός παρουσιάζει το JSON από την οπτική γωνία ενός προγραμματιστή Python. εξηγώντας τι είναι το JSON, πώς σχετίζεται με την JavaScript, ποιους τύπους Python μπορεί να αναπαραστήσει και πώς να αναλύσετε, να δημιουργήσετε, να εκτυπώσετε με όμορφο τρόπο, να επικυρώσετε και να προσαρμόσετε το JSON χρησιμοποιώντας jsonΘα εξετάσουμε επίσης περιπτώσεις χρήσης στον πραγματικό κόσμο, όπως η εργασία με αρχεία και API, καθώς και κόλπα για τον χειρισμό ένθετων δεδομένων και ακραίων περιπτώσεων όπως σφάλματα ή ειδικές τιμές όπως NaN και άπειρα.
Τι είναι το JSON και πώς σχετίζεται με τα δεδομένα Python
Το JSON, συντομογραφία του JavaScript Object Notation, είναι μια μορφή κειμένου για δομημένα δεδομένα που αρχικά δανείστηκε τη σύνταξή της από αντικείμενα και πίνακες JavaScript. Παρά τις ρίζες της JavaScript, το JSON δεν εξαρτάται από κάποια γλώσσα και υποστηρίζεται σχεδόν από κάθε σύγχρονη γλώσσα, συμπεριλαμβανομένης της Python, γεγονός που το καθιστά ιδανικό για την ανταλλαγή δεδομένων μεταξύ υπηρεσιών, πελατών και διακομιστών.
Εννοιολογικά, το JSON χρησιμοποιεί μόνο δύο σύνθετα δομικά στοιχεία: το αντικείμενο JavaScript και τον πίνακα JavaScript . Ένα αντικείμενο συμπεριφέρεται σαν ένα λεξικό Python και ένας πίνακας συμπεριφέρεται σαν μια λίστα Python. Με αυτά τα δύο, συν ένα μικρό σύνολο πρωτόγονων τύπων, το JSON μπορεί να περιγράψει σύνθετες ένθετες δομές δεδομένων.
Ένα αντικείμενο σε JavaScript (και JSON) μοιάζει με αυτό: {"key1": value1, "key2": value2}Είναι μια συλλογή ζευγών κλειδιού-τιμής, όπου τα κλειδιά είναι συμβολοσειρές και οι τιμές μπορούν να είναι οποιαδήποτε έγκυρη τιμή JSON (συμπεριλαμβανομένων άλλων αντικειμένων ή πινάκων). Αυτό αντιστοιχεί σε μεγάλο βαθμό σε μια Python dict.
Ένας πίνακας σε JavaScript (και JSON) είναι παρόμοιος με μια λίστα Python: Είναι μια ταξινομημένη συλλογή τιμών, χρησιμοποιώντας και πάλι οποιονδήποτε έγκυρο τύπο JSON. Μαζί, αντικείμενα και πίνακες μπορούν να ενσωματωθούν αυθαίρετα για να μοντελοποιήσουν πλούσια δεδομένα, όπως προφίλ χρηστών, δέντρα διαμόρφωσης ή απαντήσεις API.
Η αντιστοίχιση μεταξύ των τύπων JSON και Python είναι πολύ απλή, γι' αυτό και μερικές φορές ακούτε ανθρώπους να την αποκαλούν αστειευόμενοι «PYON» (Python Object Notation). Όταν η Python κωδικοποιεί ή αποκωδικοποιεί JSON, ισχύουν οι ακόλουθες αντιστοιχίες:
- Αντικείμενο JSON → Python
dict - Πίνακας JSON → Python
list - Συμβολοσειρά JSON → Python
str - Αριθμός JSON (ακέραιος) → Python
int - Αριθμός JSON (πραγματικός) → Python
float - JSON
true→ PythonTrue - JSON
false→ PythonFalse - JSON
null→ PythonNone
Ένας σημαντικός περιορισμός είναι ότι τα κλειδιά αντικειμένων JSON είναι πάντα συμβολοσειρές, οπότε αν κωδικοποιήσετε ένα Python dict με κλειδιά που δεν είναι συμβολοσειρές (π.χ. ακέραιοι ή πλειάδες), αυτά τα κλειδιά θα μετατραπούν σε συμβολοσειρές ή θα δημιουργήσουν σφάλματα ανάλογα με τις ρυθμίσεις σας. Το JSON είναι ιδανικό για τη διατήρηση δομημένων δεδομένων όπως διαμορφώσεις ή εγγραφές, αλλά είναι δεν ένας γενικός μηχανισμός αποσκλήρυνσης (pickling) για αυθαίρετα αντικείμενα Python.

Ενσωματωμένη ενότητα json της Python
Η Python συνοδεύεται από μια τυπική ενότητα βιβλιοθήκης που ονομάζεται json, το οποίο σας παρέχει όλα όσα χρειάζεστε για να εργαστείτε με JSON: ανάλυση συμβολοσειρών, φόρτωση από αρχεία, σειριοποίηση αντικειμένων Python και προσαρμογή του τρόπου κωδικοποίησης και αποκωδικοποίησης των δεδομένων. Δεν χρειάζεστε καμία εξωτερική εξάρτηση για τυπικές εργασίες JSON.
Οι τέσσερις βασικές λειτουργίες που θα χρησιμοποιείτε τις περισσότερες φορές είναι: json.dumps() και json.dump() για τη μετατροπή αντικειμένων Python σε JSON, και json.loads() και json.load() για τη μετάβαση από JSON πίσω σε τύπους Python. Οι εκδόσεις με "s" λειτουργούν με συμβολοσειρές, ενώ οι εκδόσεις χωρίς "s" λειτουργούν με αντικείμενα που μοιάζουν με αρχεία.
The json Ο κωδικοποιητής υποστηρίζει ένα συγκεκριμένο σύνολο τύπων Python από προεπιλογή, και συγκεκριμένα dict, list, tuple (ως πίνακες), str, αριθμοί (int, float, και απαρίθμηση που προέρχεται από ακέραιους/κινητούς αριθμούς), και τα τρία ειδικά singletons True, Falseκαι NoneΑυτά μετατρέπονται στα ισοδύναμα JSON σύμφωνα με την αντιστοίχιση που περιγράφηκε προηγουμένως.
Εάν χρειάζεται να σειριοποιήσετε προσαρμοσμένα αντικείμενα ή τύπους δεδομένων, ο σχεδιασμός της ενότητας είναι επεκτάσιμος: μπορείτε να υποκατηγοριοποιήσετε τον κωδικοποιητή JSON και να εφαρμόσετε το default() μέθοδος ή να περάσετε μια προσαρμοσμένη default λειτουργία σε json.dump() / json.dumps()Αυτό το προσαρμοσμένο άγκιστρο θα πρέπει να επιστρέψει κάτι που μπορεί να σειριοποιηθεί με JSON (όπως ένα dict or list), ή αύξηση TypeError αν δεν ξέρει πώς να χειριστεί το δεδομένο αντικείμενο.
Στο εσωτερικό, η ενότητα προσφέρει επίσης μεθόδους όπως encode() και iterencode(), τα οποία μετατρέπουν δεδομένα Python σε συμβολοσειρές JSON, με iterencode() αποδίδοντας τα κωδικοποιημένα κομμάτια σταδιακά. Αυτά χρησιμοποιούνται λιγότερο συχνά απευθείας, αλλά αξίζει να τα γνωρίζετε εάν χρειάζεται να μεταδώσετε πολύ μεγάλες απαντήσεις JSON.
Μετατροπή αντικειμένων Python σε JSON
Όταν θέλετε να μετατρέψετε δεδομένα Python σε κείμενο JSON, χρησιμοποιείτε json.dump() or json.dumps(), ανάλογα με το αν θέλετε να γράψετε απευθείας σε ένα αρχείο ή να λάβετε μια συμβολοσειρά JSON στη μνήμη. Και οι δύο συναρτήσεις μοιράζονται τις ίδιες βασικές παραμέτρους που σας επιτρέπουν να ελέγχετε τον τρόπο με τον οποίο συμπεριφέρεται η μετατροπή.
η λειτουργία json.dump(obj, fp, ...) δέχεται ένα αντικείμενο Python και ένα αντικείμενο τύπου αρχείου, και γράφει μια αναπαράσταση JSON του obj σε αυτό το αρχείο. Το αντίστοιχο στη μνήμη, json.dumps(obj, ...), επιστρέφει μια συμβολοσειρά JSON αντί να γράψει σε ένα αρχείο. Και τα δύο δέχονται μια σειρά ορισμάτων λέξεων-κλειδιών όπως skipkeys, ensure_ascii, check_circular, allow_nan, indent, separators, defaultκαι sort_keys.
Κάθε μία από αυτές τις επιλογές τροποποιεί τη συμπεριφορά κωδικοποίησης με τρόπους που έχουν μεγάλη σημασία σε πραγματικά έργα: μπορείτε να επιλέξετε αν θα παραλείψετε μη έγκυρα κλειδιά, αν θα επιβάλετε έξοδο ASCII, αν θα εκτυπώσετε όμορφα το αποτέλεσμα, αν θα ελέγξετε τον κενό χώρο, αν θα ορίσετε προσαρμοσμένη σειριοποίηση για μη τυπικά αντικείμενα ή αν θα σταθεροποιήσετε τη σειρά κλειδιών για δοκιμές και διαφορές.
Ακολουθεί η πρακτική σημασία των κύριων παραμέτρων:
skipkeys: εάν έχει οριστεί σεTrue, κλειδιά λεξικού που δεν είναι του τύπουstr,int,float,boolorNoneπαραλείπονται σιωπηλά αντί να αυξάνονταιTypeErrorΑν προτιμάτε τη γρήγορη λειτουργία όταν τα πλήκτρα είναι περίεργα, αφήστε την ως εξής.False.ensure_ascii: πότεTrue(η προεπιλογή), οι μη ASCII και οι μη εκτυπώσιμοι χαρακτήρες διαγράφονται (π.χ. ως\uXXXX) έτσι ώστε η έξοδος να παραμένει καθαρή ASCII. ΌτανFalse, Οι χαρακτήρες Unicode γράφονται ως έχουν, κάτι που είναι συνήθως καλύτερο για διαμορφώσεις ή αρχεία καταγραφής αναγνώσιμα από τον άνθρωπο.check_circular: ifTrue, ο κωδικοποιητής ελέγχει για κυκλικές αναφορές σε λίστες, ψηφία και προσαρμοσμένα κωδικοποιημένα αντικείμενα για να αποτρέψει την άπειρη αναδρομή. Ορίζοντάς το σεFalseαπενεργοποιεί αυτό το δίχτυ ασφαλείας και μπορεί να οδηγήσει σεRecursionErrorεάν οι δομές σας είναι αυτοαναφορικές.allow_nan: ifTrue, ειδικές τιμές κινητής υποδιαστολής όπωςNaN,Infinityκαι-Infinityεπιτρέπονται και κωδικοποιούνται με τρόπο συμβατό με JavaScript, παρόλο που δεν είναι αυστηρά έγκυρα JSON από την προδιαγραφή. ΕάνFalse, η προσπάθεια κωδικοποίησης τέτοιων τιμών θα αυξήσειValueError.indent: ένας μη αρνητικός ακέραιος αριθμός (ή μια συμβολοσειρά) που ελέγχει την όμορφη εκτύπωση. Ένας θετικός αριθμός σημαίνει ότι πολλά κενά ανά ένθετο επίπεδο. Μια συμβολοσειρά (όπως"\t") χρησιμοποιείται απευθείας για εσοχή.None(η προεπιλογή) επιλέγει την πιο συμπαγή αναπαράσταση, χωρίς επιπλέον νέες γραμμές πέραν των απαιτούμενων.separators: μια πλειάδα(item_separator, key_separator)ελέγχοντας τη στίξη και το κενό μεταξύ στοιχείων και μεταξύ κλειδιών και τιμών. Για το πιο αυστηρό JSON, συνήθως χρησιμοποιείτε(",", ":")για να αφαιρέσετε όλα τα προαιρετικά κενά.default: μια συνάρτηση που λαμβάνει οποιοδήποτε αντικείμενο που ο κωδικοποιητής δεν γνωρίζει πώς να χειριστεί. Πρέπει να επιστρέψει μια αντικατάσταση με δυνατότητα σειριοποίησης JSON (όπως έναdictorlist), ή αύξησηTypeErrorΑυτό είναι το κύριο εργαλείο για να κάνετε τις δικές σας κλάσεις σειριοποιήσιμες.sort_keys: ifTrue, τα λεξικά κωδικοποιούνται με ταξινομημένα κλειδιά. Αυτό είναι εξαιρετικά βολικό για δοκιμές παλινδρόμησης και αναπαραγώγιμα αποτελέσματα, όπου θέλετε τα dumps JSON να είναι σταθερά σε όλες τις εκτελέσεις.
Για ένα συγκεκριμένο παράδειγμα, φανταστείτε ότι έχετε μια μικτή λίστα Python που περιέχει ακέραιους αριθμούς και ένα λεξικό με ένα όνομα, ένα αναγνωριστικό και μια βαθμολογία κινητής υποδιαστολής. Θα μπορούσατε να δημιουργήσετε και να αποθηκεύσετε JSON ως εξής:
import pathlib
import json
path = pathlib.Path("myTextFile.json")
data =
with path.open(mode="wt") as f:
json.dump(data, f)
print(json.dumps(data, indent=4))
Το εκτυπωμένο JSON θα έχει ωραία μορφοποίηση χάρη στο indent=4, εμφανίζοντας κάθε στοιχείο λίστας και κλειδί λεξικού σε ξεχωριστή γραμμή. Αυτό κάνει τον εντοπισμό σφαλμάτων και τη χειροκίνητη επεξεργασία πολύ πιο εύκολη σε σύγκριση με μια μόνο, πυκνή γραμμή κειμένου.
Ανάλυση JSON πίσω στην Python
Για να επιστρέψετε από κείμενο JSON σε αντικείμενα Python, χρησιμοποιείτε το αντίστοιχο ζεύγος συναρτήσεων: json.load() (για αντικείμενα τύπου αρχείου) και json.loads() (για συμβολοσειρές JSON). Αυτές οι συναρτήσεις αναλύουν την είσοδο και αναδημιουργούν τύπους Python σύμφωνα με τον ίδιο πίνακα αντιστοίχισης όπως πριν.
Οι υπογραφές μοιάζουν περίπου ως εξής: json.load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, kw) και json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, kw)Σε βασικό επίπεδο, μπορείτε να τα καλέσετε μόνο με την είσοδο JSON, αλλά τα επιπλέον ορίσματα ανοίγουν την πόρτα σε πιο προηγμένη συμπεριφορά ανάλυσης.
Γάντζοι σαν object_hook και object_pairs_hook σας επιτρέπει να προσαρμόσετε τον τρόπο με τον οποίο τα αντικείμενα JSON μετατρέπονται σε δομές Python, δίνοντάς σας είτε το αποκωδικοποιημένο dict ή μια λίστα με (key, value) ζεύγη αντίστοιχα. Αυτό είναι χρήσιμο εάν θέλετε να δημιουργήσετε προσαρμοσμένες κλάσεις απευθείας από JSON ή να διατηρήσετε την ταξινόμηση με συγκεκριμένο τρόπο.
Άλλα απαιτητά στοιχεία όπως parse_float, parse_intκαι parse_constant σας επιτρέπουν να ελέγχετε τον τρόπο με τον οποίο ερμηνεύονται οι αριθμοί και τα ειδικά διακριτικά. Για παράδειγμα, ίσως θελήσετε να χρησιμοποιήσετε Decimal αντί του float για χρηματικές αξίες ή μετασχηματισμός "NaN", "inf"και "-inf" σε αντικείμενα φρουρούς της επιλογής σας.
Συνεχίζοντας το προηγούμενο παράδειγμα, μπορείτε να διαβάσετε το αρχείο JSON που γράψατε ως εξής:
with path.open(mode="rt") as f:
data = json.load(f)
print(data)
Το αποτέλεσμα που θα προκύψει θα είναι μια κανονική λίστα και λεξικό Python, για παράδειγμα , το οποίο μπορείτε να χειριστείτε με όλες τις συνήθεις λειτουργίες της Python. Από την οπτική γωνία του κώδικά σας, είναι και πάλι «απλώς δεδομένα».
Ποιους τύπους μπορεί να μετατρέψει η Python σε JSON
Δεν μπορούν όλα τα αντικείμενα Python να μετατραπούν σε JSON αμέσως μόλις τα επεξεργαστούμε. επομένως είναι χρήσιμο να θυμάστε το επιτρεπόμενο σύνολο. Οι πρακτικοί κωδικοποιητές υποστηρίζουν τους κοινούς τύπους κοντέινερ και βαθμωτών, καθώς και τις λογικές τιμές και Noneκαι να τα αντιστοιχίσετε στο ελάχιστο σύνολο τύπων JSON.
Από προεπιλογή, μπορείτε να περάσετε με ασφάλεια τα ακόλουθα αντικείμενα Python σε json.dumps():
dict(κωδικοποιημένα ως αντικείμενα JSON)listκαιtuple(κωδικοποιημένα ως πίνακες JSON)str(κωδικοποιημένο ως συμβολοσειρές JSON)intκαιfloat(κωδικοποιημένο ως αριθμοί JSON)TrueκαιFalse(κωδικοποιημένο ωςtrueκαιfalse)None(κωδικοποιημένο ωςnull)
Όταν η Python τα κωδικοποιεί αυτά, η αντιστοίχιση πίσω σε JSON είναι απλή, και αντίστροφα κατά την αποκωδικοποίηση. Για παράδειγμα, ένα Python tuple γίνεται ένας πίνακας JSON και λαμβάνετε ένα list ξανά στο φορτίο. Οι απαριθμήσεις προέρχονται από int or float μπορούν επίσης να κωδικοποιηθούν ως αριθμοί.
Όλα τα άλλα χρειάζονται προσαρμοσμένη προσαρμογή default handler (για να μετατρέψει αντικείμενα σε μια σειριοποιήσιμη αναπαράσταση) ή θα προκαλέσει TypeErrorΑυτό οφείλεται στη σχεδίαση: Το JSON προορίζεται για δεδομένα, όχι για αυθαίρετα γραφήματα αντικειμένων με συμπεριφορά και μεθόδους όπως αυτές που θα μπορούσατε να σειριοποιήσετε χρησιμοποιώντας pickle.
Για το μεγαλύτερο μέρος της καθημερινής εργασίας, αυτό το υποσύνολο τύπων καλύπτει την πλειονότητα των περιπτώσεων χρήσης, συμπεριλαμβανομένων των φορτίων API, των δέντρων διαμόρφωσης, των προτιμήσεων χρήστη, των βασικών αρχείων καταγραφής και των μικρών αρχείων "τύπου βάσης δεδομένων" για πρωτότυπα ή εργαλεία ενός χρήστη.
Όμορφη εκτύπωση, συμπαγής εκτύπωση και ταξινομημένα πλήκτρα
Η ακατέργαστη έξοδος JSON τείνει να είναι απολύτως έγκυρη αλλά δυσανάγνωστη, καθώς συχνά δημιουργείται χωρίς περιττό κενό χώρο. Για εντοπισμό σφαλμάτων, καταγραφή ή κοινή χρήση με άλλους προγραμματιστές, συχνά χρειάζεστε ευανάγνωστο, εσοχή JSON αντί για μονογραμμικό.
The indent παράμετρος του json.dumps() είναι ο κύριος μοχλός για όμορφη εκτύπωση, επιτρέποντάς σας να πείτε στην Python πόσα κενά (ή ποια συμβολοσειρά) να χρησιμοποιήσει ανά επίπεδο εσοχής. Μια τυπική επιλογή είναι indent=4, αν και ορισμένες βάσεις κώδικα προτιμούν δύο κενά ή χαρακτήρες tab, οι στυλιστικές συμβάσεις ποικίλλουν μεταξύ των έργων.
The separators Το όρισμα σάς επιτρέπει να ρυθμίσετε τον κενό χώρο ακόμη περισσότερο, δίνοντας μια πλειάδα όπως (", ", ": ") από προεπιλογή για φιλική προς τον άνθρωπο έξοδο. Εάν θέλετε την πιο συμπαγή δυνατή αναπαράσταση—για παράδειγμα, για να μειώσετε το μέγεθος του ωφέλιμου φορτίου μέσω του δικτύου—μπορείτε να ορίσετε separators=(",", ":") για να αφαιρέσετε τα κενά μετά από κόμματα και άνω και κάτω τελείες.
Όταν ενδιαφέρεστε για την ντετερμινιστική έξοδο, για παράδειγμα σε δοκιμές μονάδας ή συγκρίσεις στιγμιότυπων, ενεργοποίησης sort_keys=True κάνει τον κωδικοποιητή να εξάγει κλειδιά λεξικού με ταξινομημένη σειρά. Με αυτόν τον τρόπο, δύο εκτελέσεις που παράγουν σημασιολογικά πανομοιότυπα δεδομένα δεν διαφέρουν μόνο και μόνο επειδή τα λεξικά έτυχε να εξάγουν κλειδιά με διαφορετική ακολουθία.
Μαζί, indent, separatorsκαι sort_keys σας δίνουν πολύ έλεγχο σχετικά με το αν το JSON σας είναι βελτιστοποιημένο για μηχανές (συμπαγές, χωρίς κενά) ή για ανθρώπους (με εσοχή, ευθυγράμμιση, με σταθερό σχήμα σε όλες τις εκτελέσεις).
Ενσωματωμένα δεδομένα, στρατηγικές ανάλυσης και μοτίβα πρόσβασης
Στο πραγματικό JSON, οι επίπεδες δομές αποτελούν εξαίρεση. Συνήθως θα έχετε να κάνετε με ένθετα αντικείμενα και πίνακες. Σκεφτείτε μια τυπική εγγραφή χρήστη σε μια εφαρμογή ηλεκτρονικού εμπορίου: προσωπικές πληροφορίες, ένθετες διευθύνσεις αποστολής, ένθετα στοιχεία χρέωσης και ίσως μια λίστα παραγγελιών, καθεμία από τις οποίες αποτελεί μια πολύπλοκη δομή από μόνη της.
Κατά την αποκωδικοποίηση του JSON σε Python, τα ένθετα δεδομένα γίνονται συνδυασμοί λεξικών και λιστών, και μπορείτε να έχετε πρόσβαση σε αυτό χρησιμοποιώντας τυπικές αναζητήσεις ευρετηρίου και κλειδιού. Για ρηχές δομές, αυτό είναι απλό: data, data, και ούτω καθεξής.
Για βαθιά ένθετες ή δυναμικές δομές, ίσως προτιμάτε μια πιο γενική προσέγγιση, όπως η σύνταξη μιας μικρής αναδρομικής συνάρτησης που αναζητά κλειδιά ή που περπατάει σε ένα δέντρο από λέξεις και λίστες. Οι αναδρομικές λύσεις είναι συχνά συντομότερες και πιο ευανάγνωστες από τις επαναληπτικές όταν διασχίζετε αυθαίρετα ένθετα δεδομένα.
Το μη ένθετο (επίπεδο) JSON είναι πιο εύκολο στην άμεση πρόσβαση με κλειδιά με σκληρό κώδικα, κάτι που μπορεί να είναι απολύτως καλό για μικρά βοηθητικά προγράμματα ή όταν ελέγχετε πλήρως την είσοδο. Όταν καταναλώνετε εξωτερικά API, ωστόσο, είναι σύνηθες να γράφετε μικρές βοηθητικές συναρτήσεις που ενσωματώνουν τη δομή, ώστε να μην σπαταλάτε αλυσίδες σε όλη τη βάση κώδικα.
Ανεξάρτητα από το βάθος, το ίδιο json.loads() ισχύει η συμπεριφορά: Η συνάρτηση δέχεται μια συμβολοσειρά JSON και παράγει εγγενείς τύπους Python τους οποίους στη συνέχεια χειρίζεστε με κανονικά εργαλεία Python. Δεν απαιτείται ειδική σύνταξη πέρα από την κανονική. dict και list ευρετηρίαση
Εργασία με αρχεία JSON: Ανάγνωση, Συγγραφή και Προσθήκη
Το JSON αποτελεί μια εκπληκτικά εύχρηστη και ελαφριά μορφή αποθήκευσης για μικρά έργα, αρχεία ρυθμίσεων ή σενάρια που πρέπει να διατηρούν κάποια μόνιμη κατάσταση. Αντί να αναζητήσετε απευθείας μια πλήρη βάση δεδομένων, μπορείτε συχνά να τη γλιτώσετε με ένα ή δύο αρχεία JSON για αρκετό καιρό.
Η εγγραφή JSON σε ένα αρχείο είναι συνήθως μια διαδικασία δύο βημάτων: σειριοποίηση δεδομένων Python με json.dumps() ή απευθείας με json.dump()και, στη συνέχεια, βεβαιωθείτε ότι η συμβολοσειρά που προκύπτει έχει γραφτεί στο δίσκο. Εάν καλέσετε open('data.json', 'w'), λαμβάνετε μια λαβή αρχείου σε λειτουργία εγγραφής που είτε δημιουργεί το αρχείο είτε το περικόπτει εάν υπάρχει ήδη.
Για τις ένθετες δομές, το πρωτόκολλο δεν διαφέρει από τα επίπεδα δεδομένα: εξακολουθείς να χρησιμοποιείς το ίδιο json.dump() κλήση και οι ένθετοι συνδυασμοί λιστών και ψηφίων κωδικοποιούνται αναδρομικά. Η μόνη απόφαση που συνήθως χρειάζεται να πάρετε είναι πόση εσοχή θέλετε για αναγνωσιμότητα σε σχέση με το μέγεθος του αρχείου.
Η ανάγνωση JSON από ένα αρχείο είναι η αντίστροφη: ανοίξτε το αρχείο σε λειτουργία κειμένου, μεταβιβάστε το αντικείμενο αρχείου σε json.load()και ανακτάτε τη δομή δεδομένων Python. Και πάλι, η συμπεριφορά είναι ανεξάρτητη από το πόσο βαθιά φτάνει η ένθεση—ο αποκωδικοποιητής χειρίζεται όλα αυτά για εσάς.
Αν χρειάζεται να προσαρτήσετε δεδομένα JSON σε υπάρχοντα αρχεία, τα πράγματα γίνονται πιο λεπτά. Το ίδιο το JSON δεν υποστηρίζει την «προσάρτηση ροής» με έναν απλό τρόπο, επειδή ολόκληρο το αρχείο πρέπει να είναι έγκυρο JSON. Ένα συνηθισμένο μοτίβο είναι η αποθήκευση ενός πίνακα εγγραφών και η ανάγνωση/τροποποίηση/εγγραφή ολόκληρου του πίνακα ή η χρήση JSON οριοθετημένου με γραμμές, όπου κάθε γραμμή είναι ένα ξεχωριστό αντικείμενο JSON στο οποίο μπορείτε να προσθέσετε χωρίς να ξαναγράψετε προηγούμενες γραμμές.
JSON στον πραγματικό κόσμο: API, αποθήκευση και ανταλλαγή
Μόλις ξεκινήσετε να δημιουργείτε πραγματικές εφαρμογές, το JSON γίνεται γρήγορα ο συνδετικός κρίκος που συνδέει τους διαδικτυακούς πελάτες και διακομιστές, τις μικροϋπηρεσίες και τα API τρίτων. Είναι πολύτιμο τόσο επειδή είναι συμπαγές όσο και επειδή οι άνθρωποι μπορούν ακόμα να το διαβάσουν και να το επεξεργαστούν με αρκετή ευκολία.
Στην αλληλεπίδραση API, το JSON είναι μακράν η πιο κοινή μορφή ωφέλιμου φορτίου, ειδικά σε υπηρεσίες RESTful. Οι εφαρμογές Python συνήθως χρησιμοποιούν βιβλιοθήκες όπως requests για την αποστολή αιτημάτων HTTP και λήψη απαντήσεων JSONκαι, στη συνέχεια, αναλύστε αυτές τις απαντήσεις με json.loads() ή με βοηθητικές μεθόδους που το τυλίγουν.
Το JSON είναι επίσης μια δημοφιλής μορφή για αρχεία διαμόρφωσης και αρχεία καταγραφής, όπου η δομημένη φύση του, η οποία βασίζεται σε κλειδιά-τιμές, το καθιστά πολύ πιο εκφραστικό από το απλό κείμενο, ενώ παράλληλα παραμένει απλό σε σύγκριση με τις πλήρεις βάσεις δεδομένων. Τα στοιχεία του συστήματος μπορούν να μοιράζονται τη διαμόρφωση μέσω JSON και οι συσσωρευτές αρχείων καταγραφής μπορούν να αναλύσουν τα αρχεία καταγραφής JSON για να τα φιλτράρουν ή να τα αναλύσουν πιο εύκολα.
Μια άλλη σημαντική περίπτωση χρήσης είναι η σειριοποίηση και η αποσειριοποίηση δομών δεδομένων, η μετατροπή συλλογών στη μνήμη σε συμβολοσειρές JSON (σειριοποίηση) και στη συνέχεια η ανακατασκευή τους αργότερα (αποσειριοποίηση). Με αυτόν τον τρόπο αποθηκεύετε τις προτιμήσεις των χρηστών, μεταδίδετε δομημένα μηνύματα μέσω ουρών ή στέλνετε ένθετα αντικείμενα πέρα από τα όρια των υπηρεσιών, υπό την προϋπόθεση ότι θα τηρείτε τύπους συμβατούς με JSON ή θα παρέχετε προσαρμοσμένους κωδικοποιητές.
Πέρα από το JSON μόνο, ο κώδικας Python συχνά χρειάζεται να μετατρέψει μεταξύ JSON και άλλων μορφών, όπως XML, CSV ή απλό κείμενο. Για παράδειγμα, μπορείτε να διαβάσετε CSV από ένα παλαιότερο σύστημα, να το μετατρέψετε σε μια λίστα ψηφίων και στη συνέχεια να το αποτυπώσετε ως JSON για ένα σύγχρονο API. Ή μπορείτε να αντλήσετε JSON από ένα API, να το ομαλοποιήσετε και να γράψετε CSV για να το φορτώσουν οι αναλυτές σε υπολογιστικά φύλλα.
Μορφοποίηση, Επικύρωση και Επιπλέον Λειτουργίες σε JSON
Μόλις εξοικειωθείτε με την βασική ανάγνωση και γραφή, υπάρχουν πολλές μικρές αλλά χρήσιμες λειτουργίες που μπορείτε να εκτελέσετε σε δεδομένα JSON για να βελτιώσετε τη ροή εργασίας σας: μορφοποίηση για αναγνωσιμότητα, ισοπέδωση των ένθετων δομών, επικύρωση ότι μια συμβολοσειρά είναι πραγματικά JSON και ταξινόμηση δεδομένων για συνεπείς συγκρίσεις.
Όμορφη εκτύπωση με json.dumps(..., indent=...) είναι το πρώτο βήμα, παρέχοντάς σας όμορφα κατανεμημένες ιεραρχίες που διευκολύνουν τον εντοπισμό δομικών προβλημάτων με μια ματιά. Αυτό είναι ιδιαίτερα χρήσιμο κατά την αποσφαλμάτωση ή κατά την κοινή χρήση παραδειγμάτων στην τεκμηρίωση.
Η ισοπέδωση του ένθετου JSON μπορεί να διευκολύνει την επεξεργασία και ανάλυση κατάντη, ειδικά εάν χρειάζεται να μετατρέψετε τα δεδομένα σε μορφή πίνακα όπως CSV ή να τα τροφοδοτήσετε σε εργαλεία που αναμένουν ζεύγη κλειδιού-τιμής αντί για βαθιά ένθετα αντικείμενα. Συνήθως υλοποιείτε την ισοπέδωση χρησιμοποιώντας αναδρομή ή επαναληπτική διέλευση σε ψηφία και λίστες.
Η επικύρωση του JSON συχνά καταλήγει στην προσπάθεια ανάλυσής του και στον εντοπισμό εξαιρέσεων, ειδικά αν απλώς επαληθεύετε ότι μια συμβολοσειρά είναι συντακτικά σωστή. Για πιο αυστηρούς ελέγχους, μπορείτε να χρησιμοποιήσετε JSON Schema και εξωτερικές βιβλιοθήκες, αλλά για πολλές περιπτώσεις ένα απλό try/except γύρω json.loads() είναι αρκετό.
Η ταξινόμηση δεδομένων JSON με βάση συγκεκριμένες τιμές ή κλειδιά μπορεί να βοηθήσει κατά τη σύγκριση απαντήσεων, δημιουργία σταθερών στιγμιότυπων για δοκιμές ή απλώς διασφάλιση ότι παρόμοια αντικείμενα ομαδοποιούνται. Μπορείτε είτε να ταξινομήσετε τις υποκείμενες λίστες και τα ψηφία Python πριν από την απόρριψη είτε να βασιστείτε σε sort_keys=True όταν η εστίαση είναι στην ταξινόμηση κλειδιών μέσα στα αντικείμενα.
Χειρισμός σφαλμάτων κατά την εργασία με JSON
Ακόμα και καλά δομημένα συστήματα μπορούν να εκτεθούν σε λανθασμένη μορφή JSON ή σε μη αναμενόμενα δεδομένα, επομένως, η ισχυρή διαχείριση σφαλμάτων γύρω από την ανάλυση και την κωδικοποίηση JSON είναι ζωτικής σημασίας. Η Python εκφράζει αυτά τα προβλήματα μέσω εξαιρέσεων και ο ιδιωματικός τρόπος αντιμετώπισής τους είναι η αναδίπλωση των λειτουργιών σε try...except μπλοκ.
Κατά την αποκωδικοποίηση JSON, το πιο συνηθισμένο πρόβλημα είναι η μη έγκυρη σύνταξη, όπως η απουσία εισαγωγικών γύρω από τα ονόματα των ιδιοτήτων ή τα τελικά κόμματα. json η ενότητα θα εμφανίσει ένα σφάλμα αποκωδικοποίησης (συνήθως json.JSONDecodeError), τα οποία μπορείτε να εντοπίσετε και να καταγράψετε ή να μετατρέψετε σε εύχρηστα μηνύματα.
Για παράδειγμα, η προσπάθεια ανάλυσης μιας κατεστραμμένης συμβολοσειράς μπορεί να οδηγήσει σε ένα σφάλμα όπως: Failed to decode JSON: Expecting property name enclosed in double quotes: line 1 column 29 (char 28)Αυτού του είδους το μήνυμα δεν σας ενημερώνει μόνο ότι η ανάλυση απέτυχε, αλλά και σε ποιο σημείο της εισόδου μπερδεύτηκε ο αναλυτής.
Από την πλευρά της κωδικοποίησης, μπορεί να πατήσετε TypeError όταν προσπαθείτε να σειριοποιήσετε μη υποστηριζόμενους τύπους, or ValueError αν το απαγορεύσεις NaN και άπειρα μέσω allow_nan=False αλλά τα δεδομένα σας περιέχουν τέτοιες τιμές. Οι κυκλικές αναφορές σε κοντέινερ μπορούν επίσης να ενεργοποιήσουν RecursionError αν απενεργοποιήσετε τους κυκλικούς ελέγχους.
Η βέλτιστη πρακτική είναι να αντιμετωπίζονται οι λειτουργίες JSON ως λανθασμένες εισόδους/εξόδου, ειδικά κατά την ανάγνωση από πηγές δικτύου ή εξωτερικά αρχεία: να υποθέτετε πάντα ότι κάτι μπορεί να πάει στραβά και να εντοπίζετε τις εξαιρέσεις ανάλογα, ενδεχομένως προσθέτοντας επίπεδα επικύρωσης για να επιβάλλετε πιο συγκεκριμένους περιορισμούς στα δεδομένα σας. Αναδίπλωση json.loads() ή βοηθητικές μέθοδοι API σε try...except Το blocks προστατεύει τον υπόλοιπο κώδικά σας από διαδοχικές αποτυχίες και σας επιτρέπει να επιστρέψετε εύχρηστα σφάλματα JSON στους πελάτες όταν είναι σκόπιμο.
Χρήση JSON με Web APIs σε Python
Τα περισσότερα web API με τα οποία επικοινωνείτε μέσω Python θα στέλνουν και θα λαμβάνουν JSON, και η τυπική στοίβα ανάπτυξης συνδυάζει το requests βιβλιοθήκη (για HTTP) με το json ενότητα (για ανάλυση και δημιουργία JSON). Αυτός ο συνδυασμός κάνει την ενσωμάτωση API να φαίνεται πολύ φυσική.
Ένα συνηθισμένο μοτίβο είναι να καλείτε ένα τελικό σημείο API, να ελέγχετε ότι ο κωδικός κατάστασης απόκρισης υποδεικνύει επιτυχία και, στη συνέχεια, να αναλύετε το σώμα του JSON . Από εκεί μπορείτε να αποκτήσετε πρόσβαση σε πεδία, να χειριστείτε ένθετα δεδομένα και να αντιστοιχίσετε την απόκριση στα δικά σας μοντέλα τομέα ή να προβάλετε αντικείμενα.
Η διαχείριση σφαλμάτων αποκτά ιδιαίτερη σημασία όταν εμπλέκονται κλήσεις δικτύου, επειδή μπορεί να αντιμετωπίσετε όχι μόνο μη έγκυρο JSON, αλλά και χρονικά όρια, σφάλματα σύνδεσης ή αποτυχίες από την πλευρά του διακομιστή που ανταποκρίνονται με HTML αντί για JSON. Αναδίπλωση json.loads() ή βοηθητικές μέθοδοι API σε try...except Το blocks προστατεύει τον υπόλοιπο κώδικά σας από διαδοχικές αποτυχίες.
Μόλις αναλυθεί, το API JSON συμπεριφέρεται όπως ακριβώς οποιαδήποτε άλλη δομή δεδομένων Python, επομένως όλες οι τεχνικές που συζητήθηκαν προηγουμένως - όμορφη εκτύπωση, ισοπέδωση, επικύρωση, ταξινόμηση - εφαρμόζονται άμεσα. Η άνεση στην εναλλαγή μεταξύ δεδομένων Python και JSON αποτελεί τεράστια ώθηση στην παραγωγικότητα όταν συνδέετε υπηρεσίες. Εάν εστιάζετε στη δημιουργία πραγματικών εφαρμογών , η έγκαιρη προσοχή στα μοτίβα χειρισμού JSON θα εξοικονομήσει χρόνο εντοπισμού σφαλμάτων αργότερα.
Το JSON σε Python αφορά λιγότερο μια μεμονωμένη κλήση συνάρτησης και περισσότερο μια εργαλειοθήκη: σαφείς αντιστοιχίσεις τύπων, ευέλικτες παράμετροι κωδικοποίησης, hooks για προσαρμοσμένους τύπους, απλή αλλά ισχυρή είσοδος/έξοδος αρχείων και ισχυρά μοτίβα για την ανάλυση, τη μορφοποίηση και την επικύρωση δεδομένων από τον έξω κόσμο, τα οποία καθιστούν το JSON μια φυσική επιλογή για προγραμματιστές Python που ασχολούνται με σύγχρονες εφαρμογές που βασίζονται σε δεδομένα.
