Εισαγωγή
Σε αυτόν τον οδηγό, θα ρίξουμε μια ματιά στον τρόπο ανάγνωσης και εγγραφής δεδομένων JSON από και σε ένα αρχείο στην Python, χρησιμοποιώντας το
json
μονάδα μέτρησης.
JSON (Σημειογραφία αντικειμένου JavaScript) είναι μια εξαιρετικά δημοφιλής μορφή για σειριοποίηση δεδομένων, δεδομένου του πόσο γενικά εφαρμόσιμο και ελαφρύ είναι – ενώ είναι και αρκετά φιλικό προς τον άνθρωπο. Το πιο αξιοσημείωτο είναι ότι χρησιμοποιείται ευρέως στον κόσμο της ανάπτυξης ιστού, όπου πιθανότατα θα συναντήσετε σειριακά αντικείμενα JSON που αποστέλλονται από API REST, διαμόρφωση εφαρμογής ή ακόμα και απλή αποθήκευση δεδομένων.
Δεδομένης της επικράτησης του, η ανάγνωση και η ανάλυση αρχείων (ή συμβολοσειρών) JSON είναι αρκετά συνηθισμένη και η εγγραφή JSON για αποστολή είναι εξίσου συνηθισμένη. Σε αυτόν τον οδηγό – θα ρίξουμε μια ματιά στον τρόπο αξιοποίησης του json
ενότητα για ανάγνωση και εγγραφή JSON σε Python.
Εγγραφή JSON σε αρχείο με Python με json.dump() και json.dumps()
Για να γράψουμε τα περιεχόμενα JSON σε ένα αρχείο στην Python – μπορούμε να χρησιμοποιήσουμε json.dump()
και json.dumps()
. Αυτά είναι χωριστές μεθόδους και να επιτύχετε διαφορετικά αποτελέσματα:
json.dumps()
– Σειριοποιεί ένα αντικείμενο σε μορφή JSON κορδόνιjson.dump()
– Σειροποίηση ενός αντικειμένου σε μια ροή JSON για αποθήκευση σε αρχεία ή υποδοχές
Σημείωση: Το "s" στο "dumps" είναι στην πραγματικότητα συντομογραφία "χορδή απόρριψης".
Η φυσική μορφή του JSON είναι παρόμοια με το a χάρτη στην επιστήμη των υπολογιστών – ένας χάρτης του key-value
ζεύγη. Στην Python, α λεξικό είναι μια υλοποίηση χάρτη, επομένως φυσικά θα είμαστε σε θέση να αντιπροσωπεύουμε πιστά το JSON μέσω ενός dict
. Ένα λεξικό μπορεί να περιέχει άλλα ένθετα λεξικά, πίνακες, booleans ή άλλους πρωτόγονους τύπους όπως ακέραιους αριθμούς και συμβολοσειρές.
:::
Σημείωση: Η ενσωματωμένη json Το πακέτο προσφέρει πολλές πρακτικές μεθόδους που μας επιτρέπουν να κάνουμε μετατροπή μεταξύ JSON και λεξικών.
:::
Τούτου λεχθέντος, ας εισάγουμε το json
ενότητα, ορίστε ένα λεξικό με ορισμένα δεδομένα και στη συνέχεια μετατρέψτε το σε JSON πριν το αποθηκεύσετε σε αρχείο:
import json
data = {
'employees' : [
{
'name' : 'John Doe',
'department' : 'Marketing',
'place' : 'Remote'
},
{
'name' : 'Jane Doe',
'department' : 'Software Engineering',
'place' : 'Remote'
},
{
'name' : 'Don Joe',
'department' : 'Software Engineering',
'place' : 'Office'
}
]
}
json_string = json.dumps(data)
print(json_string)
Αυτο εχει ως αποτελεσμα:
{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}
Εδώ, έχουμε ένα απλό λεξικό με λίγα employees
, καθένα από τα οποία έχει ένα name
, department
και place
. ο dumps()
λειτουργία του json
ενότητα χωματερές ένα λεξικό σε περιεχόμενα JSON και επιστρέφει α Συμβολοσειρά JSON.
Μόλις γίνει σειριακή, μπορείτε να αποφασίσετε να το στείλετε σε άλλη υπηρεσία που θα το αποσειρώσει ή, ας πούμε, θα το αποθηκεύσει. Για να αποθηκεύσουμε αυτήν τη συμβολοσειρά JSON σε ένα αρχείο, απλώς θα ανοίξουμε ένα αρχείο σε λειτουργία εγγραφής και θα το καταγράψουμε. Εάν δεν θέλετε να εξαγάγετε τα δεδομένα σε μια ανεξάρτητη μεταβλητή για μελλοντική χρήση και θέλετε απλώς να τα απορρίψετε σε ένα αρχείο, μπορείτε να παραλείψετε το dumps()
λειτουργία και χρήση dump()
instad:
with open('json_data.json', 'w') as outfile:
outfile.write(json_string)
with open('json_data.json', 'w') as outfile:
json.dump(json_string, outfile)
Οποιοδήποτε αντικείμενο που μοιάζει με αρχείο μπορεί να περάσει στο δεύτερο όρισμα του dump()
λειτουργία, ακόμα κι αν δεν είναι πραγματικό αρχείο. Ένα καλό παράδειγμα αυτού θα ήταν μια υποδοχή, η οποία μπορεί να ανοίξει, να κλείσει και να γραφτεί σε ένα αρχείο.
Ανάγνωση JSON από αρχείο με Python με json.load() και json.loads()
Η αντιστοίχιση μεταξύ των περιεχομένων του λεξικού και μιας συμβολοσειράς JSON είναι απλή, επομένως είναι εύκολη η μετατροπή μεταξύ των δύο. Η ίδια λογική όπως και με dump()
και dumps()
εφαρμόζεται σε load()
και loads()
. Μου αρέσει πολύ json.dumps()
, τη json.loads()
η συνάρτηση δέχεται μια συμβολοσειρά JSON και τη μετατρέπει σε λεξικό, ενώ json.load()
σας επιτρέπει να φορτώσετε ένα αρχείο:
import json
with open('json_data.json') as json_file:
data = json.load(json_file)
print(data)
Αυτο εχει ως αποτελεσμα:
{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}
Εναλλακτικά, ας διαβάσουμε μια συμβολοσειρά JSON σε ένα λεξικό:
import json
python_dictionary = json.loads(json_string)
print(python_dictionary)
Το οποίο έχει επίσης ως αποτέλεσμα:
{'employees': [{'name': 'John Doe', 'department': 'Marketing', 'place': 'Remote'}, {'name': 'Jane Doe', 'department': 'Software Engineering', 'place': 'Remote'}, {'name': 'Don Joe', 'department': 'Software Engineering', 'place': 'Office'}]}
Αυτό είναι ιδιαίτερα χρήσιμο για την ανάλυση αποκρίσεων REST API που στέλνουν JSON. Αυτά τα δεδομένα έρχονται σε εσάς ως συμβολοσειρά, στην οποία μπορείτε στη συνέχεια να μεταβιβάσετε json.loads()
απευθείας και έχετε ένα πολύ πιο διαχειρίσιμο λεξικό για να δουλέψετε!
Ταξινόμηση, Pretty-Printing, Separators και Encoding
Κατά τη σειριοποίηση των δεδομένων σας σε JSON με Python, η τυπική μορφή που στοχεύει στην ελαχιστοποίηση της απαιτούμενης μνήμης για τη μετάδοση μηνυμάτων δεν είναι πολύ ευανάγνωστη, καθώς τα κενά διαστήματα καταργούνται. Αν και αυτή είναι η ιδανική συμπεριφορά για τη μεταφορά δεδομένων (οι υπολογιστές δεν ενδιαφέρονται για την αναγνωσιμότητα, αλλά ενδιαφέρονται για το μέγεθος) – μερικές φορές μπορεί να χρειαστεί να κάνετε μικρές αλλαγές, όπως να προσθέσετε κενό διάστημα για να το κάνετε αναγνώσιμο από τον άνθρωπο.
Ρίξτε μια ματιά στον πρακτικό μας οδηγό για την εκμάθηση του Git, με βέλτιστες πρακτικές, πρότυπα αποδεκτά από τον κλάδο και συμπεριλαμβανόμενο φύλλο εξαπάτησης. Σταματήστε τις εντολές του Git στο Google και πραγματικά μαθαίνουν το!
Σημείωση: json.dump()
/json.dumps()
και json.load()
/json.loads()
Όλα παρέχουν μερικές επιλογές μορφοποίησης.
Pretty-Printing JSON σε Python
Κάνοντας το JSON αναγνώσιμο από τον άνθρωπο (γνωστός και ως “όμορφη εκτύπωση”) είναι τόσο εύκολη όσο η μετάδοση μιας ακέραιας τιμής για το indent
παραμέτρου:
import json
data = {'people':[{'name': 'Scott', 'website': 'stackabuse.com', 'from': 'Nebraska'}]}
print(json.dumps(data, indent=4))
Αυτό τσαλακώνει μια εσοχή 4 διαστημάτων σε κάθε νέο λογικό μπλοκ:
{
"people": [
{
"website": "stackabuse.com",
"from": "Nebraska",
"name": "Scott"
}
]
}
Μια άλλη επιλογή είναι να χρησιμοποιήσετε το εργαλείο γραμμής εντολών – json.tool
. Με αυτό, μπορείτε να εκτυπώσετε όμορφα το JSON στη γραμμή εντολών χωρίς να επηρεαστεί η μεταδιδόμενη συμβολοσειρά και απλώς να επηρεαστεί ο τρόπος που εμφανίζεται στον τυπικό σωλήνα εξόδου:
$ echo '{"people":[{"name":"Scott", "website":"stackabuse.com", "from":"Nebraska"}]}' | python -m json.tool
{
"people": [
{
"name": "Scott",
"website": "stackabuse.com"
"from": "Nebraska",
}
]
}
Ταξινόμηση αντικειμένων JSON κατά πλήκτρα
Με όρους JSON:
"Ένα αντικείμενο είναι ένα μη ταξινομημένο σύνολο ζευγών ονόματος/τιμών."
Η παραγγελία κλειδιού δεν είναι εγγυημένη, αλλά είναι πιθανό να χρειαστεί να εκτελέσετε την εντολή κλειδιού. Για να επιτύχετε την παραγγελία, μπορείτε να περάσετε True
στο sort_keys
επιλογή κατά τη χρήση json.dump()
or json.dumps()
:
import json
data = {'people':[{'name': 'Scott', 'website': 'stackabuse.com', 'from': 'Nebraska'}]}
print(json.dumps(data, sort_keys=True, indent=4))
Αυτο εχει ως αποτελεσμα:
{
"people": [
{
"from": "Nebraska",
"name": "Scott",
"website": "stackabuse.com"
}
]
}
Κείμενο και κωδικοποίηση ASCII
Από προεπιλογή, json.dump()
και json.dumps()
θα διασφαλίσει ότι το κείμενο στο συγκεκριμένο λεξικό Python έχει κωδικοποίηση ASCII. Εάν υπάρχουν χαρακτήρες που δεν είναι ASCII, τότε γίνεται αυτόματη διαφυγή τους, όπως φαίνεται στο ακόλουθο παράδειγμα:
import json
data = {'item': 'Beer', 'cost':'£4.00'}
jstr = json.dumps(data, indent=4)
print(jstr)
{
"item": "Beer",
"cost": "u00a34.00"
}
Αυτό δεν είναι πάντα αποδεκτό και σε πολλές περιπτώσεις μπορεί να θέλετε να διατηρήσετε τους χαρακτήρες Unicode αμετάβλητους. Για να το κάνετε αυτό, ορίστε το ensure_ascii
επιλογή για να False
:
jstr = json.dumps(data, ensure_ascii=False, indent=4)
print(jstr)
{
"item": "Beer",
"cost": "£4.00"
}
Παράλειψη τύπων δεδομένων προσαρμοσμένου κλειδιού
Εάν ένα κλειδί στο λεξικό σας είναι μη πρωτόγονου τύπου (str
, int
, float
, bool
or None
) Του TypeError
ανυψώνεται όταν προσπαθείτε να απορρίψετε περιεχόμενο JSON σε ένα αρχείο. Μπορείτε να παραλείψετε αυτά τα κλειδιά μέσω του skipkeys
διαφωνία:
jstr = json.dumps(data, skipkeys=True)
Ενεργοποίηση και απενεργοποίηση κυκλικού ελέγχου
Εάν μια ιδιότητα ενός αντικειμένου JSON αναφέρεται στον εαυτό της ή ένα άλλο αντικείμενο που παραπέμπει στο γονικό αντικείμενο - δημιουργείται ένα απεριόριστα αναδρομικό JSON. Η άπειρη αναδρομή συνήθως έχει ως αποτέλεσμα την ταχεία κατανομή της μνήμης έως ότου εξαντληθεί η μνήμη μιας συσκευής και στην περίπτωση απόρριψης JSON, RecursionError
αυξάνεται και η απόρριψη διακόπτεται.
Αυτό ρυθμίζεται από το check_circular
σημαία, που είναι True
από προεπιλογή και αποτρέπει πιθανά ζητήματα κατά τη σύνταξη κυκλικών εξαρτήσεων. Για να το απενεργοποιήσετε, μπορείτε να το ρυθμίσετε σε `False:
jstr = json.dumps(data, check_circular=False)
Σημειώστε, ωστόσο, ότι αυτό είναι υψηλά δεν προτείνεται.
Ενεργοποίηση και απενεργοποίηση NaNs
Τιμές NaN, όπως π.χ -inf
, inf
και nan
μπορεί να εισχωρήσει σε αντικείμενα που θέλετε να σειριοποιήσετε ή να αποσειροποιήσετε. Πρότυπο JSON δεν επιτρέπει για τιμές NaN, αλλά εξακολουθούν να φέρουν λογική τιμή που μπορεί να θέλετε να μεταδώσετε σε ένα μήνυμα. Από την άλλη πλευρά – μπορεί να θέλετε να επιβάλετε αυτές τις τιμές NaN δεν είναι μεταδόθηκε και αντ' αυτού δημιουργήστε μια εξαίρεση. ο allow_nan
η σημαία έχει οριστεί σε True
από προεπιλογή, και σας επιτρέπει να σειριοποιήσετε και να αποσειροποιήσετε τιμές NaN, αντικαθιστώντας τις με τα ισοδύναμα JavaScript (Inifinity
, -Infinity
και NaN
).
Εάν ορίσετε τη σημαία σε False
αντ' αυτού – θα μεταβείτε σε μια αυστηρά τυποποιημένη μορφή JSON, η οποία προκαλεί α ValueError
εάν τα αντικείμενά σας περιέχουν χαρακτηριστικά με αυτές τις τιμές:
jstr = json.dumps(data, allow_nan=False)
Αλλαγή διαχωριστικών
Στο JSON, τα κλειδιά διαχωρίζονται από τις τιμές με άνω και κάτω τελεία (:
) και τα στοιχεία χωρίζονται μεταξύ τους με κόμμα (,
):
key1:value1,
key2:value2
Τα προεπιλεγμένα διαχωριστικά για την ανάγνωση και την εγγραφή JSON στην Python είναι (', ', ': ')
με κενά διαστήματα μετά τα κόμματα και τις άνω τελείες. Μπορείτε να τα αλλάξετε για να παρακάμψετε τα κενά και έτσι να κάνετε το JSON λίγο πιο συμπαγές ή να αλλάξετε πλήρως τα διαχωριστικά με άλλους ειδικούς χαρακτήρες για διαφορετική αναπαράσταση:
jstr = json.dumps(data, separators=(',', ':'))
Ζητήματα συμβατότητας με Python 2
Εάν χρησιμοποιείτε μια παλαιότερη έκδοση της Python (2.x) – ενδέχεται να συναντήσετε ένα TypeError
ενώ προσπαθείτε να απορρίψετε τα περιεχόμενα JSON σε ένα αρχείο. Δηλαδή, εάν τα περιεχόμενα περιέχουν χαρακτήρα που δεν είναι ASCII, α TypeError
ανατρέφεται, ακόμη και αν περνάτε το όρισμα κωδικοποίησης, όταν χρησιμοποιείτε το json.dump()
μέθοδος:
with open('json_data.json', 'w', encoding='utf-8') as outfile:
json.dump(json_string, outfile, ensure_ascii=False)
Εάν συναντήσετε αυτήν την περίπτωση άκρης, η οποία έχει διορθωθεί από τότε σε επόμενες εκδόσεις Python - δοκιμάστε να χρησιμοποιήσετε json.dumps()
αντ 'αυτού, και γράψτε τα περιεχόμενα της συμβολοσειράς σε ένα αρχείο αντί να κάνετε streaming τα περιεχόμενα απευθείας σε ένα αρχείο.
Συμπέρασμα
Σε αυτόν τον οδηγό, σας παρουσιάσαμε το json.dump()
, json.dumps()
, json.load()
, να json.loads()
μεθόδους, οι οποίες βοηθούν στη σειριοποίηση και αποσειροποίηση συμβολοσειρών JSON.
Στη συνέχεια, ρίξαμε μια ματιά στο πώς μπορείτε να ταξινομήσετε αντικείμενα JSON, να τα εκτυπώσετε όμορφα, να αλλάξετε την κωδικοποίηση, να παραλείψετε προσαρμοσμένους τύπους δεδομένων κλειδιών, να ενεργοποιήσετε ή να απενεργοποιήσετε τους κυκλικούς ελέγχους και εάν επιτρέπονται τα NaN, καθώς και πώς να αλλάξετε τα διαχωριστικά για σειριοποίηση και αποσειροποίηση.
Καθώς το JSON είναι ένας από τους πιο δημοφιλείς τρόπους σειριοποίησης δομημένων δεδομένων, πιθανότατα θα πρέπει να αλληλεπιδράτε με αυτό αρκετά συχνά, ειδικά όταν εργάζεστε σε εφαρμογές web. της Python json
Η ενότητα είναι ένας πολύ καλός τρόπος για να ξεκινήσετε, αν και πιθανότατα θα το βρείτε απλός είναι μια άλλη εξαιρετική εναλλακτική που είναι πολύ λιγότερο αυστηρή στη σύνταξη JSON.