សំណួរសំភាសន៍រចនាប្រព័ន្ធ អាចជាការបើកចំហរ ដូច្នេះវាពិបាកពេកក្នុងការដឹងពីវិធីត្រឹមត្រូវក្នុងការរៀបចំ។ ឥឡូវនេះខ្ញុំអាចបំបែកការរចនានៃ 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 }
ស្វែងរកអ្នកប្រើប្រាស់ដែលបានបញ្ចប់ការងារត្រូវធ្វើអតិបរមា៖
ប្រសិនបើអ្នកក្រឡេកមើលទិន្នន័យ អ្នកនឹងឃើញថា មានអ្នកប្រើប្រាស់ច្រើននាក់ ដែលម្នាក់ៗមានលេខសម្គាល់អ្នកប្រើប្រាស់តែមួយ ហើយធាតុដែលត្រូវធ្វើនីមួយៗមានលក្ខណៈសម្បត្តិហៅថា 'បានបញ្ចប់'។ ចូរយើងស្វែងយល់ថាតើអ្នកប្រើប្រាស់ណាដែលបានបញ្ចប់កិច្ចការអតិបរមា។
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()
- ប្រសិនបើការគ្រប់គ្រងប្រភេទទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នក ទទួលបានទិន្នន័យមេតា ហើយសរសេរឧបករណ៍ឌិកូដ និងឧបករណ៍បំប្លែងកូដផ្ទាល់ខ្លួនរបស់អ្នកដើម្បីអាន និងសរសេរទិន្នន័យ។
