קריאה וכתיבה של JSON לקובץ ב-Python

מבוא

במדריך זה, נסקור כיצד לקרוא ולכתוב נתוני 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" ב"מזבלות" הוא למעשה קיצור של "מחרוזת dump".

הפורמט הטבעי של JSON דומה ל-a מַפָּה במדעי המחשב - מפה של key-value זוגות. בפייתון, א מילון הוא יישום מפה, כך שמטבע הדברים נוכל לייצג את JSON נאמנה באמצעות a dict. מילון יכול להכיל מילונים מקוננים אחרים, מערכים, בוליאנים או סוגים פרימיטיביים אחרים כמו מספרים שלמים ומחרוזות.

:::

הערה: מובנית ג'סון החבילה מציעה מספר שיטות נוחות המאפשרות לנו להמיר בין 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 וממירה אותה למילון, while 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-Print, מפרידים וקידוד

כאשר מעבירים את הנתונים שלך בסידרה ל-JSON עם Python, הפורמט הסטנדרטי שמטרתו למזער את הזיכרון הנדרש להעברת הודעות אינו קריא במיוחד מכיוון שהרווחים הלבנים בוטלו. אמנם זו ההתנהגות האידיאלית להעברת נתונים (למחשבים לא אכפת מהקריאה, אבל אכפת מהגודל) - לפעמים ייתכן שיהיה עליך לבצע שינויים קטנים, כמו הוספת רווח לבן כדי להפוך אותו לקריאה אנושית.

עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!

הערה: json.dump()/json.dumps() ו json.load()/json.loads() כולם מספקים כמה אפשרויות עיצוב.

די-הדפסת JSON ב-Python

הפיכת JSON לקריא לאדם (aka "מודפס יפה") קל כמו להעביר ערך של מספר שלם עבור ה 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 כברירת מחדל, ומונע בעיות אפשריות בעת כתיבת תלות מעגלית. כדי לכבות את זה, אתה יכול להגדיר אותו ל'שקר:

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)

אם אתה נתקל במקרה הקצה הזה, שתוקן מאז בגרסאות פייתון עוקבות - נסה להשתמש json.dumps() במקום זאת, וכתוב את תוכן המחרוזת לקובץ במקום להזרים את התוכן ישירות לקובץ.

סיכום

במדריך זה, הכרנו אותך עם json.dump(), json.dumps(), json.load(), ו json.loads() שיטות, אשר מסייעות בהמשכה וסיריאליזציה של מחרוזות JSON.

לאחר מכן, בדקנו כיצד ניתן למיין אובייקטי JSON, להדפיס אותם יפה, לשנות את הקידוד, לדלג על סוגי נתוני מפתח מותאמים אישית, להפעיל או להשבית בדיקות מעגליות והאם NaNs מותרים, כמו גם כיצד לשנות את המפרידים עבור סריאליזציה וסיריאליזציה.

מכיוון ש-JSON היא אחת הדרכים הפופולריות ביותר לסידור נתונים מובנים, סביר להניח שתצטרך לקיים איתו אינטראקציה בתדירות גבוהה, במיוחד כשאתה עובד על יישומי אינטרנט. של פייתון json מודול הוא דרך מצוינת להתחיל, אם כי כנראה תמצא את זה פשוטג'סון היא אלטרנטיבה מצוינת נוספת שמחמירה הרבה פחות על תחביר JSON.

בול זמן:

עוד מ Stackabuse