JSON ជាមួយ Python

សំណួរសំភាសន៍រចនាប្រព័ន្ធ អាចជាការបើកចំហរ ដូច្នេះវាពិបាកពេកក្នុងការដឹងពីវិធីត្រឹមត្រូវក្នុងការរៀបចំ។ ឥឡូវនេះខ្ញុំអាចបំបែកការរចនានៃ Amazon, Microsoft និង Adobe បន្ទាប់ពីទិញ សៀវភៅ​នេះ. ពិនិត្យឡើងវិញប្រចាំថ្ងៃ សំណួររចនា ហើយខ្ញុំសន្យាថាអ្នកអាចបំបែកការរចនាជុំ។

តើ JSON ជាអ្វី?

JSON តំណាងឱ្យ JavaScript Object Notation ។ វាផ្អែកលើវាក្យសម្ព័ន្ធ JavaScript ។ តាមន័យធៀប ទម្រង់ JSON គឺស្រដៀងនឹងកូដសម្រាប់បង្កើតវត្ថុ JavaScript ។ ទោះបីជា JSON ផ្អែកលើ Javascript ក៏ដោយ JSON គឺខុសពី Javascript ហើយ JavaScript ខ្លះគឺ មិនមាន JSON នៅទីនេះក្នុងអត្ថបទនេះ យើងនឹងសិក្សាអំពីរបៀបប្រើ JSON ជាមួយ Python។

JSON គឺជាទម្រង់អត្ថបទឯករាជ្យទាំងស្រុងនៃភាសា ក្នុងពេលតែមួយប្រើអនុសញ្ញាដែលស៊ាំជាមួយអ្នកសរសេរកម្មវិធីនៃភាសា C-family រួមមាន C, C++, C#, Java, JavaScript, Perl, ពស់ថ្លាន់និងអ្នកផ្សេងទៀតជាច្រើន។ ដោយសារតែ JSON នេះត្រូវបានចាត់ទុកថាជាភាសាផ្លាស់ប្តូរទិន្នន័យដ៏ល្អ។

ដើម្បីធ្វើសៀរៀល និងបញ្ជូនទិន្នន័យដែលមានរចនាសម្ព័ន្ធតាមរយៈការតភ្ជាប់បណ្តាញ JSON ត្រូវបានគេប្រើជាញឹកញាប់។ ទោះបីជា XML ត្រូវបានប្រើសម្រាប់គោលបំណងដូចគ្នាក៏ដោយ យើងប្រើ JSON ជាចម្បងសម្រាប់ការបញ្ជូនទិន្នន័យរវាងម៉ាស៊ីនមេ និង កម្មវិធីបណ្ដាញ. JSON ត្រូវបានគេពេញចិត្តជាង XML ព្រោះវាស្រាល។ អ្នកអាចស្វែងយល់បន្ថែមអំពី JSON នៅលើផ្លូវការ គេហទំព័រ JSON.

វត្ថុ JSON៖

វត្ថុ JSON មើលទៅស្រដៀងនឹងវត្ថុ JavaScript និងវចនានុក្រម Python ។ ដូចជាវត្ថុ JavaScript និងវចនានុក្រម Python វត្ថុ JSON ក៏ជាសំណុំនៃឈ្មោះ និងតម្លៃដែលមិនមានលំដាប់ដែលព័ទ្ធជុំវិញដោយដង្កៀបអង្កាញ់។ គូ​តម្លៃ​ឈ្មោះ​ត្រូវ​បាន​តំណាង​ដោយ​ឈ្មោះ​ក្នុង​សញ្ញា​សម្រង់​ទ្វេ​ដែល​តាម​ពីក្រោយ​ដោយ​សញ្ញា​និង​តាម​ដោយ​តម្លៃ។

{
"Name":"John"
}

វត្ថុមួយអាចមានគូតម្លៃឈ្មោះច្រើន និងគូតម្លៃឈ្មោះផងដែរ។ តម្លៃឈ្មោះត្រូវបានបំបែកដោយសញ្ញាក្បៀស។

{
  "id": "0001",
  "type": "donut",
  "name": "Cake",
  "ppu": 0.55,
  "batters":
    {
      "batter":
        [
          { "id": "1001", "type": "Regular" },
          { "id": "1002", "type": "Chocolate" },
          { "id": "1003", "type": "Blueberry" },
          { "id": "1004", "type": "Devil's Food" }
        ]
    },
  "topping":
    [
      { "id": "5001", "type": "None" },
      { "id": "5002", "type": "Glazed" },
      { "id": "5005", "type": "Sugar" },
      { "id": "5007", "type": "Powdered Sugar" },
      { "id": "5006", "type": "Chocolate with Sprinkles" },
      { "id": "5003", "type": "Chocolate" },
      { "id": "5004", "type": "Maple" }
    ]
}

JSON ក៏គាំទ្រផងដែរ។ ប្រភេទទិន្នន័យ ដូចជាលេខ ខ្សែអក្សរ បញ្ជី និងវត្ថុ។

JSON ជាមួយ Python៖

ចូរចាប់ផ្តើមស្វែងយល់ពីរបៀបនៃទិន្នន័យ JSON នៅក្នុង Python ជាមួយនឹងឧទាហរណ៍កូដមួយចំនួន។ Python ភ្ជាប់មកជាមួយកញ្ចប់ json ដែលមានស្រាប់ដែលយើងអាចប្រើដើម្បីធ្វើការជាមួយទិន្នន័យ JSON ។ យើងត្រូវនាំចូល json នៅក្នុងស្គ្រីប Python របស់យើង ដើម្បីប្រើប្រាស់កញ្ចប់នេះ។

import json

សៀរៀល និង សៀរៀល

ដំណើរការនៃការបំប្លែងទិន្នន័យ JSON ទៅជាបណ្តុំនៃបៃដែលត្រូវរក្សាទុកក្នុងអង្គចងចាំ ឬចែករំលែកនៅទូទាំងបណ្តាញត្រូវបានគេហៅថា ការអ៊ិនកូដ។ Serialization គឺជាដំណើរការនៃការអ៊ិនកូដទិន្នន័យ JSON ។

ដំណើរការបញ្ច្រាសនៃសៀរៀលគឺ Deserialization។ ដំណើរការនៃការឌិកូដទិន្នន័យត្រូវបានគេហៅថា Deserialization ។

នៅក្នុងពាក្យសាមញ្ញ យើងអាចនិយាយបានថា serialization និង Deserialization មានន័យថាការសរសេរ និងអានទិន្នន័យទៅក្នុង memory។ ការអ៊ិនកូដគឺសម្រាប់សរសេរទិន្នន័យ ចំណែកការឌិកូដគឺសម្រាប់អានទិន្នន័យ។

តម្រៀបទិន្នន័យ JSON៖

កញ្ចប់ json inbuilt របស់ Python ផ្តល់នូវវិធីសាស្រ្ត dump() និង dumps() សម្រាប់ការបំប្លែងវត្ថុ Python ទៅជា JSON ។ តោះមើលភាពខុសគ្នារវាងវិធីសាស្រ្តទាំងពីរនេះ៖

បោះចោល() បោះចោល()
dump() បំប្លែងវត្ថុ Python ទៅជាវត្ថុ JSON ហើយសរសេរវាទៅជាឯកសារ។ ដើម្បីបំប្លែងវត្ថុ Python ទៅជា JSON string dumps() ត្រូវបានប្រើ
ឯកសារលទ្ធផលដែលទិន្នន័យត្រូវរក្សាទុកត្រូវតែឆ្លងកាត់ជាអាគុយម៉ង់ ឈ្មោះឯកសារមិនត្រូវបានទាមទារទេ។
លឿនជាងកន្លែងចាក់សំរាម () យឺតជាងការបោះចោល ()

តារាងខាងក្រោមពន្យល់ពីរបៀបដែលវត្ថុ Python ត្រូវបានបំប្លែងទៅជាវត្ថុ JSON ដែលសមមូល។

វត្ថុ Python វត្ថុ JSON សមមូល
ឌុក វត្ថុ
បញ្ជី អារេ
ធូបល។ អារេ
str ខ្សែអក្សរ
int លេខ
float លេខ
ជាការពិត ជាការពិត
មិនពិត មិនពិត
គ្មាន ទទេ

dump() ឧទាហរណ៍៖

តោះមើលឧទាហរណ៍ដើម្បីបំប្លែងវត្ថុ python ទៅជាវត្ថុ JSON ហើយរក្សាទុកវាទៅជាឯកសារដោយប្រើវិធីសាស្រ្ត dump() ។ នេះគឺជាទិន្នន័យ python របស់យើង។

python_data=
    {
      "batter":
        [
          { "id": "1001", "type": "Regular" },
          { "id": "1002", "type": "Chocolate" },
          { "id": "1003", "type": "Blueberry" },
          { "id": "1004", "type": "Devil's Food" }
        ]
    }

ហើយលេខកូដ Python គឺ៖

with open('Data_file.json','w') as filename:
    json.dump(python_data,filename)

dump() យកអាគុយម៉ង់ពីរ៖

  • python_data
  • filename-Data_file.json ដែលជាឯកសារលទ្ធផលដែលវត្ថុ JSON ត្រូវរក្សាទុក។

dumps() ឧទាហរណ៍៖

វិធីសាស្រ្ត dumps() បំប្លែងវត្ថុ Python ទៅជាខ្សែអក្សរ JSON ។

json_string=json.dumps(python_data)

នៅទីនេះយើងមិនឆ្លងកាត់ឈ្មោះឯកសារអាគុយម៉ង់ផ្សេងទៀតដូចដែលយើងបានធ្វើនៅក្នុង dump() ដែលមិនត្រូវបានទាមទារ។

អាគុយម៉ង់ពាក្យគន្លឹះសម្រាប់ dump() និង dumps():

ចូល​បន្ទាត់៖

ទោះបីជា JSON ងាយស្រួលអានក៏ដោយ វាកាន់តែងាយស្រួលអាននៅពេលធ្វើទ្រង់ទ្រាយត្រឹមត្រូវ។ អ្នក​អាច​ប្រើ​អាគុយម៉ង់​ពាក្យ​គន្លឹះ​បន្ថែម​ដែល​ហៅ​ថា​ចូល​បន្ទាត់​ដើម្បី​ផ្លាស់​ប្តូរ​ការ​ចូល​បន្ទាត់​សម្រាប់​រចនាសម្ព័ន្ធ​ដែល​ជាប់។ ប្រតិបត្តិកូដខាងក្រោម ហើយកត់សម្គាល់ភាពខុសគ្នានៃទម្រង់ជាមួយការប្រើប្រាស់ការចូលបន្ទាត់។

print(json.dumps(python_data))
print(json.dumps(python_data,indent=4))

សញ្ញាបំបែក៖

មានអំណះអំណាងពាក្យគន្លឹះមួយទៀតដែលយើងអាចប្រើដើម្បីផ្លាស់ប្តូរទម្រង់គឺសញ្ញាបំបែក។ សញ្ញាបំបែកគឺជា (item_separator, key_separator) tuple ។ តម្លៃលំនាំដើមគឺ (', ',': ') ។ ដើម្បីទទួលបាន JSON បង្រួមបំផុតប្រើ (',',':') ដែលលុបបំបាត់ចន្លោះទទេ។

print(json.dumps(python_data))
print(json.dumps(python_data,separators=(',',':')))

សូមមើល ឯកសារ សម្រាប់បញ្ជីបន្ថែមនៃអាគុយម៉ង់ពាក្យគន្លឹះ។

Deserializing ទិន្នន័យ JSON៖

Deserialization បំប្លែងវត្ថុ JSON ទៅជាវត្ថុ Python រៀងៗខ្លួន។ យើងអាចប្រើ load() និង loads() សម្រាប់ deserializing ។

load() ទទួលបានទិន្នន័យរបស់វាពីឯកសារ ចំណែក loads() ទទួលបានទិន្នន័យរបស់វាពី string object ។

ខាងក្រោម តារាង ពន្យល់ពីរបៀបដែលវត្ថុ JSON ត្រូវបានបំប្លែងទៅជាវត្ថុ Python រៀងៗខ្លួន៖

វត្ថុ JSON វត្ថុ Python
វត្ថុ ផ្តាច់ការ
អារេ បញ្ជី
ខ្សែអក្សរ str
ទទេ គ្មាន
លេខ (int) int
លេខ (ពិត) float
ជាការពិត ជាការពិត
មិនពិត មិនពិត

តារាង​នេះ​មិន​មែន​ជា​តារាង​ផ្ទុយ​គ្នា​ពិត​ប្រាកដ​ដែល​យើង​បាន​ឃើញ​ក្នុង​ការ​សៀរៀល​ទេ។ នោះ​ក៏​ព្រោះ​តែ​នៅ​ពេល​ដែល​យើង​អ៊ិនកូដ​វត្ថុ​មួយ យើង​ប្រហែល​ជា​មិន​អាច​ទទួល​បាន​វត្ថុ​ដូច​គ្នា​វិញ​បន្ទាប់​ពី​ឌិកូដ។

សូមពិនិត្យមើលឧទាហរណ៍ខាងក្រោម យើងកំពុងអ៊ិនកូដ tuple មួយ។ សមមូល tuple នៃវត្ថុ JSON គឺជាអារេ។ ការឌិកូដអារេផ្តល់បញ្ជី។ ដូច្នេះការអ៊ិនកូដនិងការឌិកូដនៃ tuple លទ្ធផលនៅក្នុងបញ្ជីមួយ។

import json

input_data=('a','b',1,2,3)
encoded_data=json.dumps(input_data)
decoded_data=json.loads(encoded_data)
print(input_data==decoded_data)
print(type(input_data))
print(type(decoded_data))
print(input_data==tuple(decoded_data))

Load() ឧទាហរណ៍៖

load() method បំប្លែង JSON object ទៅជា Python object ហើយទទួលបានវាពីឯកសារ។ សូមចងចាំថាយើងបានបង្កើត Data_file.json ខណៈពេលកំពុងធ្វើសៀរៀលទិន្នន័យ។ តោះប្រើឯកសារដូចគ្នានៅទីនេះ។

import json

with open('Data_file.json','r') as filename:
    data=json.load(filename)

print(data)

ក្នុងករណីដែលអ្នកមិនធ្វើ ប្រភេទនៃទិន្នន័យ អ្នកកំពុងផ្ទុក បន្ទាប់មកចាំថាប្រភេទនៃទិន្នន័យលទ្ធផលអាចជាអ្វីដែលមាននៅក្នុងតារាងបំប្លែង។

Loads() ឧទាហរណ៍៖

loads() ទទួលបានការបញ្ចូលរបស់វាពីខ្សែអក្សរជំនួសឱ្យឯកសារ។

import json

json_data="""
{
      "batter":
        [
          { "id": "1001", "type": "Regular" },
          { "id": "1002", "type": "Chocolate" },
          { "id": "1003", "type": "Blueberry" },
          { "id": "1004", "type": "Devil's Food" }
        ]
    }
"""

print(json.loads(json_data))

ឧទាហរណ៍ជាក់ស្តែង៖

ដើម្បីអនុវត្តសូមប្រើ JSONPlaceholderដែលផ្តល់ទិន្នន័យ JSON គំរូ។ យើងអាចទទួលបានទិន្នន័យពីសេវាកម្ម JSONPlaceholder ដោយធ្វើការស្នើសុំ API ទៅកាន់វា។ Python ផ្តល់កញ្ចប់ inbuilt ហៅថា 'requests' ដែលយើងអាចប្រើដើម្បីធ្វើការហៅ API ។

បង្កើតឯកសារ Python ជាមួយនឹងឈ្មោះនៃជម្រើសរបស់អ្នក និងគ្រប់ទីកន្លែងដែលអ្នកចង់បាន ហើយបន្ទាប់មកនាំចូលកញ្ចប់ខាងក្រោម។

import json
import requests

យើងត្រូវធ្វើសំណើ API ទៅកាន់សេវាកម្ម JSONPlaceholder សម្រាប់ /todos endpoint។ នៅពេលដែលការហៅ API ទទួលបានជោគជ័យ យើងនឹងទទួលបាន 200 ជាលេខកូដស្ថានភាព។

response = requests.get("https://jsonplaceholder.typicode.com/todos")
print(response.status_code)

ដើម្បីលុបគុណលក្ខណៈអត្ថបទនៃវត្ថុឆ្លើយតប យើងអាចប្រើវិធី json.loads ឬ json() ។ ដូចដែលយើងបានឃើញខាងលើ ការផ្ទុកគឺជាមុខងារ json ដែលអាចត្រូវបានប្រើមិនត្រឹមតែដើម្បីញែកទិន្នន័យខ្សែអក្សរប៉ុណ្ណោះទេ ប៉ុន្តែក៏ត្រូវប្រើជាមួយបរិបទសំណើផងដែរ។

response = requests.get("https://jsonplaceholder.typicode.com/todos")
print(json.loads(response.text))

.json គឺជាវិធីសាស្រ្តនៃ class requests.models.Response។ វាត្រឡប់ទិន្នន័យ json ពីការឆ្លើយតបនៃសំណើ។

response = requests.get("https://jsonplaceholder.typicode.com/todos")
print(response.json())

លទ្ធផលនៃ json.loads និង .json គឺដូចគ្នា។

response = requests.get("https://jsonplaceholder.typicode.com/todos")
print(response.json()==json.loads(response.text))

ប្រសិនបើអ្នកពិបាកលោតរវាងឯកសារ Python និង terminal របស់អ្នករាល់ពេលដែលអ្នកផ្លាស់ប្តូរកូដ នោះវាងាយស្រួលក្នុងការដំណើរការស្គ្រីបរបស់អ្នកក្នុងរបៀបអន្តរកម្ម។ អ្នកអាចដំណើរការក្នុងរបៀបអន្តរកម្មដោយប្រើ -i នៅពេលយើងដំណើរការស្គ្រីប។ អត្ថប្រយោជន៍គឺមិនត្រឹមតែវាដំណើរការស្គ្រីបប៉ុណ្ណោះទេ ប៉ុន្តែអ្នកក៏អាចធ្វើបានផងដែរ។ ចូលប្រើទិន្នន័យទាំងអស់។ ពីស្គ្រីបនៅក្នុងស្ថានីយខ្លួនឯង។

PS C:\Users\Gopi\Desktop\backup\myPython\freelancer> python -i code1.py
>>> json.loads(response.text)==response.json()
True
>>> response.status_code
200

វិធីសាស្ត្រ response.json() ត្រឡប់បញ្ជី។ អ្នកអាចធ្វើប្រតិបត្តិការបញ្ជីទាំងអស់ជាមួយនឹងធាតុដែលបានត្រឡប់មកវិញ។

response = requests.get("https://jsonplaceholder.typicode.com/todos")
todos=response.json()
print(type(todos))
print(todos[10])

យើង​កំពុង​បោះពុម្ព​ធាតុ​ចៃដន្យ​មួយ​ចំនួន​ដើម្បី​ទទួល​បាន​គំនិត​មួយ​ថា​តើ​ធាតុ​ត្រូវ​ធ្វើ​មើល​ទៅ​ដូច​ម្តេច។ អ្នកក៏អាចមើលធាតុដោយចូលទៅកាន់ចំណុចបញ្ចប់នៅក្នុងកម្មវិធីរុករក។

{
  'userId': 1, 
  'id': 11, 
  'title': 'vero rerum temporibus dolor', 
  'completed': True
}

JSON ជាមួយ Pythonពិន

ស្វែងរកអ្នកប្រើប្រាស់ដែលបានបញ្ចប់ការងារត្រូវធ្វើអតិបរមា៖

ប្រសិនបើអ្នកក្រឡេកមើលទិន្នន័យ អ្នកនឹងឃើញថា មានអ្នកប្រើប្រាស់ច្រើននាក់ ដែលម្នាក់ៗមានលេខសម្គាល់អ្នកប្រើប្រាស់តែមួយ ហើយធាតុដែលត្រូវធ្វើនីមួយៗមានលក្ខណៈសម្បត្តិហៅថា 'បានបញ្ចប់'។ ចូរយើងស្វែងយល់ថាតើអ្នកប្រើប្រាស់ណាដែលបានបញ្ចប់កិច្ចការអតិបរមា។

import requests

todos_completed_by_each_user={}

response = requests.get("https://jsonplaceholder.typicode.com/todos")
todos = response.json()

for todo in todos:
    if todo['completed']:
        try:
            todos_completed_by_each_user[todo['userId']]+=1
        except KeyError:
            todos_completed_by_each_user[todo['userId']]=1

#sorting the dictionary based on maximum completed todos in

លំដាប់បញ្ច្រាស

max_todos_by_user = sorted(todos_completed_by_each_user.items(),
                   key=lambda x: x[1], reverse=True)

#Gets the

ចំនួនអតិបរមា

 of todos completed
max_todos = max_todos_by_user[0][1]

users=[]

#Gets the list of users who have completed the maximum todos
for user,no_of_todos in max_todos_by_user:
    if no_of_todos<max_todos:
        continue
    users.append(str(user))

max_users = " and ".join(users)
print(max_users)

ឥឡូវនេះយើងទទួលបានបញ្ជីអ្នកប្រើប្រាស់ដែលបានបញ្ចប់ ចំនួនអតិបរមា នៃការងារត្រូវធ្វើ។ តោះព្យាយាមបោះពុម្ពលទ្ធផលតាមរបៀបដ៏ល្អ។

s='s' if len(users)>1 else ""
print(f'User{s} {max_users} completed {max_todos} TODOs')

លទ្ធផលនឹងដូចជា៖

Users 5 and 10 and 8 completed 12 TODOs

ឥឡូវនេះ ចូរយើងបង្កើតឯកសារ json ដែលមានឈ្មោះថា “completed_todos.json” ដែលផ្ទុកនូវអ្វីដែលត្រូវបំពេញសម្រាប់អ្នកប្រើប្រាស់ដែលបានបញ្ចប់ ចំនួនអតិបរមា នៃការងារត្រូវធ្វើ។

def filtered_todos(todo):
    has_max_count = str(todo["userId"]) in users
    is_complete = todo["completed"]
    return is_complete and has_max_count

# Write filtered TODOs to file.
with open("filtered_todos.json", "w") as data_file:
    filtered_todos = list(filter(filtered_todos, todos))
    json.dump(filtered_todos, data_file, indent=2)

ប្រសិនបើអ្នកមិនដឹងអំពីវិធីសាស្ត្រ filter() ទេ វិធីសាស្ត្រ filter() ត្រងលំដាប់ដោយជំនួយពីមុខងារដែលផ្តល់សុពលភាពធាតុនីមួយៗនៃលំដាប់ថាពិតឬមិនពិត។

នៅទីនេះ វិធីសាស្ត្រ filter() កំពុងប្រើមុខងារមួយហៅថា filtered_todos() ដែលពិនិត្យមើលថាតើមានលេខសម្គាល់អ្នកប្រើប្រាស់នៅក្នុងបញ្ជីអ្នកប្រើប្រាស់ដែលបានបញ្ចប់ការងារត្រូវធ្វើអតិបរមាដែរឬទេ ហើយវាក៏ពិនិត្យមើលថាតើការងារត្រូវធ្វើត្រូវបានបញ្ចប់សម្រាប់អ្នកប្រើប្រាស់ដែលបានផ្តល់ឱ្យឬអត់។ ប្រសិនបើលក្ខខណ្ឌទាំងពីរនេះជាការពិត នោះយើងកំពុងសរសេរអ្វីដែលត្រូវធ្វើនៅក្នុងឯកសារលទ្ធផលរបស់យើងដោយប្រើវិធីសាស្រ្ត dump() ។

ឯកសារលទ្ធផល “completed_todos.json” មានតែបញ្ជីការងារត្រូវធ្វើដែលបានបញ្ចប់របស់អ្នកប្រើប្រាស់ដែលបានបញ្ចប់ការងារត្រូវធ្វើអតិបរមាប៉ុណ្ណោះ។

ការដាក់សៀរៀល និងលុបសៀរៀលវត្ថុ Python ផ្ទាល់ខ្លួន៖

តោះបង្កើតវត្ថុ python ផ្ទាល់ខ្លួនរបស់យើង។

class EmployeeDetails:
    def __init__(self,firstname,lastname,age):
        self.firstname = firstname
        self.lastname = lastname
        self.age=age

    def get_name(self):
        return self.firstname+' '+self.lastname

emp=EmployeeDetails('John','Terry',29)
emp_name=emp.get_name()

យើងកំពុងបង្កើត class មួយហៅថា EmployeeDetails និង method មួយដែលត្រឡប់ឈ្មោះរបស់និយោជិត។ តោះបង្កើតវត្ថុមួយសម្រាប់វា។

ឥឡូវព្យាយាមធ្វើស៊េរីអថេរ emp_name ហើយមើលថាមានអ្វីកើតឡើង។

PS C:\Users\Gopi\Desktop\backup\myPython\freelancer> python -i sample.py
John Terry
>>> json.dumps(emp_name)
'"John Terry"'

យើងមិនប្រឈមមុខនឹងបញ្ហាណាមួយទេ នៅពេលព្យាយាមធ្វើស៊េរី emp_name ដែលជាប្រភេទខ្សែអក្សរ។ សូមមើលថាតើមានអ្វីកើតឡើងនៅពេលដែលយើងព្យាយាមធ្វើស៊េរីវត្ថុ python ផ្ទាល់ខ្លួន emp ដែលយើងបានបង្កើត។

>>> json.dumps(emp)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'EmployeeDetails' is not JSON serializable

យើងកំពុងទទួលបានកំហុស "EmployeeDetails" មិនអាច JSON សៀរៀលបានទេ។ ទោះបីជាយើងអាចអ៊ិនកូដប្រភេទទិន្នន័យដែលភ្ជាប់មកជាមួយ python ភាគច្រើនក៏ដោយ ម៉ូឌុល json មិនដឹងពីរបៀបធ្វើសៀរៀលវត្ថុ python ផ្ទាល់ខ្លួនទេ។

ធ្វើឱ្យរចនាសម្ព័ន្ធទិន្នន័យសាមញ្ញ៖

ជំនួសឱ្យការព្យាយាមអ៊ិនកូដវត្ថុផ្ទាល់ខ្លួនដោយផ្ទាល់ អ្វីដែលយើងអាចធ្វើបានគឺបំប្លែងវត្ថុផ្ទាល់ខ្លួនទៅជាតំណាងផ្សេងទៀត ដែលម៉ូឌុល json យល់ បន្ទាប់មកបម្លែងវាទៅជា JSON ។

ចូរយើងយល់ពីរបៀបដែលវាដំណើរការដោយមានជំនួយពីឧទាហរណ៍មួយ។ ដើម្បីតំណាងឱ្យចំនួនកុំផ្លិច Python ផ្តល់នូវការភ្ជាប់មកជាមួយ ប្រភេទ​ទិន្នន័យ "ស្មុគស្មាញ" ។ ចំនួនកុំផ្លិចត្រូវបានបង្ហាញក្នុងទម្រង់ a+bj ដែល 'a' គឺជាផ្នែកពិត ហើយ 'b' គឺជាផ្នែកស្រមើលស្រមៃ។

>>> import json
>>> z=2+5j
>>> type(z)
<class 'complex'>
>>> json.dumps(z)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'complex' is not JSON serializable

ដោយសារចំនួនកុំផ្លិចមិនអាច JSON សៀរៀលបាន នោះយើងព្យាយាមបំប្លែងចំនួនកុំផ្លិចទៅជាទម្រង់មួយ ដែលម៉ូឌុល json យល់។

ដើម្បីបង្កើតចំនួនកុំផ្លិច អ្វីដែលយើងត្រូវការគឺមានតែផ្នែកពិត និងផ្នែកស្រមើលស្រមៃប៉ុណ្ណោះ។

>>> z.real
2.0
>>> z.imag
5.0

នៅពេលដែលយើងបញ្ជូនផ្នែកពិត និងផ្នែកស្រមើលស្រមៃទៅអ្នកបង្កើតស្មុគស្មាញ យើងនឹងទទួលបានចំនួនកុំផ្លិច។

>>> complex(2,5)==z
True

វាជាការសំខាន់ដើម្បីយល់ពីរបៀបបំបែកទំនៀមទម្លាប់មួយ។ ប្រភេទ​ទិន្នន័យ ទៅលើសមាសធាតុសំខាន់ៗរបស់វា ដើម្បីធ្វើ serialize និង deserialize វា។

ការអ៊ិនកូដប្រភេទទិន្នន័យផ្ទាល់ខ្លួន៖

ឥឡូវនេះយើងមានសមាសធាតុសំខាន់ៗទាំងអស់ដើម្បីបង្កើតចំនួនកុំផ្លិច។ ដើម្បីបំប្លែងចំនួនកុំផ្លិចទៅជា JSON អ្វីដែលយើងអាចធ្វើបានគឺបង្កើតមុខងារអ៊ិនកូដផ្ទាល់ខ្លួនរបស់យើង ហើយបញ្ជូនវាទៅវិធីសាស្ត្រ dump()។

ខាងក្រោម​នេះ​ជា​វិធីសាស្ត្រ​ដែល​យើង​អាច​ប្រើ​ដើម្បី​បំប្លែង​លេខ​កុំផ្លិច។ ក្រៅពីលេខកុំផ្លិច ប្រសិនបើយើងបញ្ជូនប្រភេទទិន្នន័យផ្ទាល់ខ្លួនផ្សេងទៀតជាការបញ្ចូលទៅក្នុងមុខងារ វានឹងបោះកំហុសប្រភេទ។

def encode_complex_numbers(z):
    if isinstance(z,complex):
        return (z.real,z.imag)
    else:
        type_name=z.__class__.__name__
        raise TypeError(f'Object of type {type_name} is not JSON serializable')

នៅពេលណាដែលយើងព្យាយាមបំប្លែងប្រភេទទិន្នន័យផ្ទាល់ខ្លួនដែលមិនមែនជា JSON serializable មុខងារបំប្លែងកូដរបស់យើងនឹងត្រូវបានហៅ។

>>> json.dumps(2+5j,default=encode_complex_numbers)
'[2.0, 5.0]'
>>> json.dumps(emp,default=encode_complex_numbers)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\Gopi\AppData\Local\Programs\Python\Python36-32\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "sample.py", line 18, in encode_complex_numbers
    raise TypeError(f'Object of type {type_name} is not JSON serializable')
TypeError: Object of type EmployeeDetails is not JSON serializable

សូម​កត់​សម្គាល់​ថា ឥឡូវ​នេះ​យើង​អាច​ធ្វើ​លេខ​កុំផ្លិច​ដោយ​ប្រើ​មុខងារ 'encode_complex_numbers' របស់​យើង។ សម្រាប់ប្រភេទទិន្នន័យផ្ទាល់ខ្លួនផ្សេងទៀត យើងនឹងទទួលបានប្រភេទកំហុស។ អ្នកអាចទទួលបានសំណួរអំពីរបៀបដែលយើងដឹងថាកំហុសត្រូវបានបោះពុម្ពចេញពីកូដរបស់យើង។ សូមកត់សម្គាល់បន្ទាត់ដែលបានបន្លិច គំរូគឺជាឈ្មោះឯកសារដែលមុខងារអ៊ិនកូដរបស់ខ្ញុំមានវត្តមាន អ្នកនឹងឃើញឈ្មោះឯកសាររបស់អ្នកនៅកន្លែងនោះ។ វាត្រូវបានហៅជំនួសឱ្យវិធីសាស្ត្រ default() ។

ផងដែរ រឿងមួយទៀតដែលត្រូវកត់សម្គាល់គឺយើងកំពុងត្រឡប់ផ្នែកពិត និងស្រមើលស្រមៃនៃចំនួនកុំផ្លិចនៅក្នុង tuple ដែលម៉ូឌុល json យល់។

ជំនួសឱ្យការបដិសេធវិធីសាស្ត្រ default() វិធីសាស្រ្តជំនួសគឺដើម្បីបង្កើតថ្នាក់រងហៅថា 'ComplexEncoder' នៅក្រោមថ្នាក់ស្តង់ដារ JSONEncoder ។

class ComplexEncoder(json.JSONEncoder):
    def default(self,z):
        if isinstance(z,complex):
            return (z.real,z.imag)
        else:
            return super().default(z)

យើងមិនមែនទេ ដោះស្រាយកំហុសប្រភេទ នៅក្នុងកូដ យើងអនុញ្ញាតឱ្យថ្នាក់មូលដ្ឋានគ្រប់គ្រងវា។ ឥឡូវនេះយើងមានជម្រើសពីរដើម្បីអ៊ិនកូដលេខស្មុគស្មាញ។ យើងមានទាំងការប្រើប្រាស់ ComplexEncoder class ក្នុង dump() method ឬយើងអាចបង្កើត object សម្រាប់វា ហើយហៅ method encode()។

>>> json.dumps(2+5j,cls=ComplexEncoder)
'[2.0, 5.0]'
>>> encoder=ComplexEncoder()
>>> encoder.encode(2+5j)
'[2.0, 5.0]'

ការឌិកូដប្រភេទទិន្នន័យផ្ទាល់ខ្លួន៖

ទោះបីជាយើងមានចំនួនពិត និងស្រមើស្រមៃនៃចំនួនកុំផ្លិច តើវាគ្រប់គ្រាន់ក្នុងការបង្កើតចំនួនកុំផ្លិចឡើងវិញទេ? ទេ អនុញ្ញាតឱ្យយើងមើលឃើញថា នៅពេលដែលយើងឌិកូដលទ្ធផលនៃមុខងារការអ៊ិនកូដរបស់យើង អ្វីដែលយើងទទួលបានមកវិញ។

>>> json_format=json.dumps(2+5j,cls=ComplexEncoder)
>>> json.loads(json_format)
[2.0, 5.0]

អ្វីដែលយើងត្រូវទទួលបានគឺចំនួនកុំផ្លិច ប៉ុន្តែអ្វីដែលយើងទទួលបានគឺគ្រាន់តែជាបញ្ជីប៉ុណ្ណោះ។ ប្រសិនបើ​យើង​ត្រូវ​បង្កើត​ចំនួន​កុំផ្លិច​ឡើងវិញ យើង​ត្រូវ​បញ្ជូន​តម្លៃ​ទៅ​អ្នក​បង្កើត​ស្មុគស្មាញ។ អ្វីដែលយើងខកខានគឺទិន្នន័យមេតា។

ការយល់ដឹងអំពីទិន្នន័យមេតា៖

ទិន្នន័យមេតាមានន័យថាចំនួនព័ត៌មានអប្បបរមាដែលគ្រប់គ្រាន់ និងចាំបាច់ដើម្បីបង្កើតវត្ថុឡើងវិញ។

ម៉ូឌុល json ចង់ឱ្យប្រភេទទិន្នន័យផ្ទាល់ខ្លួនទាំងអស់ត្រូវបានតំណាងជាទម្រង់ដែលយល់។ តោះបង្កើតឯកសារមួយឈ្មោះថា complex_data.json ហើយបន្ថែមព័ត៌មាន metadata ទាំងអស់។ វត្ថុខាងក្រោមដែលតំណាងឱ្យចំនួនកុំផ្លិច គឺជាព័ត៌មានទិន្នន័យមេតា បន្ថែមវាទៅក្នុងឯកសារ។

{
    "__complex__": true,
    "real": 2,
    "imag": 5
}

នេះជាគន្លឹះ __complex__ គឺជាទិន្នន័យមេតាដែលយើងកំពុងស្វែងរក។ អ្នកកំណត់តម្លៃណាមួយទៅកូនសោ __complex__ វាមិនមានបញ្ហាទេ។ អ្វីទាំងអស់ដែលយើងនឹងធ្វើគឺផ្ទៀងផ្ទាត់ថាតើសោមានឬអត់

def decode_complex_number(dct):
    if '__complex__' in dct:
        return complex(dct['real'],dct['imag'])
    return dct

យើងកំពុងសរសេរមុខងារផ្ទាល់ខ្លួនរបស់យើងដើម្បីឌិកូដចំនួនកុំផ្លិច ដូចដែលយើងបានធ្វើសម្រាប់ការអ៊ិនកូដ។ សម្រាប់ប្រភេទទិន្នន័យផ្ទាល់ខ្លួនផ្សេងទៀត យើងកំពុងអនុញ្ញាតឱ្យឧបករណ៍ឌិកូដលំនាំដើមដើម្បីដោះស្រាយ។

នៅពេលណាដែលវិធីសាស្ត្រផ្ទុក () ត្រូវបានហៅ យើងចង់ឱ្យឧបករណ៍ឌិកូដផ្ទាល់ខ្លួនរបស់យើង ឌិកូដទិន្នន័យ ជំនួសឱ្យការឱ្យឧបករណ៍ឌិកូដមូលដ្ឋានដោះស្រាយ។ ដើម្បីសម្រេចបាននូវចំណុចនេះ យើងត្រូវការមុខងារឌិកូដរបស់យើងដែលត្រូវបញ្ជូនទៅប៉ារ៉ាម៉ែត្រ object_hook ។

with open('complex_data.json','r') as data_file:
    data = data_file.read()
    z=json.loads(data,object_hook=decode_complex_number)

លទ្ធផលគឺ:

>>> z
(2+5j)
>>> type(z)
<class 'complex'>

object_hook គឺស្រដៀងនឹងវិធីសាស្ត្រលំនាំដើមនៃ dumps()។ ប្រសិនបើអ្នកមានលេខស្មុគស្មាញច្រើនជាងមួយ អ្នកអាចបន្ថែមវាទៅ complex_data.json ហើយដំណើរការកូដម្តងទៀត។

[
  {
      "__complex__": true,
      "real": 2,
      "imag": 5
  },
  {
      "__complex__": true,
      "real": 7,
      "imag": 10
  },
  {
      "__complex__": true,
      "real": 13,
      "imag": 15
  }
]

ឥឡូវនេះលទ្ធផលរបស់យើងនឹងជាបញ្ជីនៃចំនួនកុំផ្លិច។

>>> z
[(2+5j), (7+10j), (13+15j)]

ដូចដែលបានបន្ថែមថ្នាក់អ៊ិនកូដឌ័រផ្ទាល់ខ្លួនរបស់យើងនៅក្រោមថ្នាក់ JSONEncoder យើងអាចមានថ្នាក់ឌិកូដផ្ទាល់ខ្លួនរបស់យើងនៅក្រោមថ្នាក់ JSONDecoder ជំនួសឱ្យការបដិសេធ object_hook ។

class ComplexDecoder(json.JSONDecoder):
    def __init__(self,*args,**kwargs):
        super().__init__(object_hook=self.object_hook, *args, **kwargs)
    def object_hook(self,dct):
        if '__complex__' in dct:
            return complex(dct['real'],dct['imag'])
        else:
            return super().decode(dct)

with open('complex_data.json','r') as data_file:
    data = data_file.read()
    z=json.loads(data,cls=ComplexDecoder)
    print(z)

សេចក្តីសន្និដ្ឋាន:

យើងបានអានអំពី JSON ជាមួយ Python នៅក្នុងអត្ថបទនេះ។ ចូរយើងព្យាយាមចងចាំចំណុចសំខាន់ៗពីអ្វីដែលយើងបានរៀនកន្លងមក។

  • នាំចូលកញ្ចប់ json ដែលមានស្រាប់
  • អានទិន្នន័យដោយប្រើ load ឬ loads()
  • ដំណើរការទិន្នន័យ
  • សរសេរដំណើរការដោយប្រើ dump() ឬ dumps()
  • ប្រសិនបើការគ្រប់គ្រងប្រភេទទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នក ទទួលបានទិន្នន័យមេតា ហើយសរសេរឧបករណ៍ឌិកូដ និងឧបករណ៍បំប្លែងកូដផ្ទាល់ខ្លួនរបស់អ្នកដើម្បីអាន និងសរសេរទិន្នន័យ។
បទសម្ភាសន៍រចនាប្រព័ន្ធបំបែក
Translate »