Làm việc với JSON
1. Giới thiệu
Phần tiêu đề “1. Giới thiệu”JSON (JavaScript Object Notation) là định dạng văn bản dùng để lưu trữ và truyền tải dữ liệu có cấu trúc. JSON rất phổ biến trong web development và API.
Tại sao học JSON?
Phần tiêu đề “Tại sao học JSON?”- ✅ Định dạng chuẩn cho Web APIs
- ✅ Dễ đọc cho cả người và máy
- ✅ Hỗ trợ cấu trúc dữ liệu phức tạp (nested)
- ✅ Python hỗ trợ JSON rất tốt
Ví dụ JSON
Phần tiêu đề “Ví dụ JSON”{ "name": "Alice", "age": 25, "city": "New York", "skills": ["Python", "JavaScript", "SQL"], "is_student": false}2. Module json
Phần tiêu đề “2. Module json”Python có module json built-in.
import json3. Kiểu dữ liệu JSON vs Python
Phần tiêu đề “3. Kiểu dữ liệu JSON vs Python”| JSON | Python |
|---|---|
object {} |
dict |
array [] |
list |
| string | str |
| number (int) | int |
| number (float) | float |
| true | True |
| false | False |
| null | None |
4. Chuyển đổi Python → JSON (Serialization)
Phần tiêu đề “4. Chuyển đổi Python → JSON (Serialization)”4.1 - json.dumps() - Chuyển object thành string
Phần tiêu đề “4.1 - json.dumps() - Chuyển object thành string”import json
# Python dictionaryperson = { "name": "Alice", "age": 25, "city": "New York", "skills": ["Python", "JavaScript"]}
# Chuyển thành JSON stringjson_string = json.dumps(person)print(json_string)# {"name": "Alice", "age": 25, "city": "New York", "skills": ["Python", "JavaScript"]}
print(type(json_string)) # <class 'str'>4.2 - json.dumps() với formatting đẹp
Phần tiêu đề “4.2 - json.dumps() với formatting đẹp”import json
person = { "name": "Alice", "age": 25, "city": "New York"}
# indent=4 để format đẹpjson_string = json.dumps(person, indent=4)print(json_string)Output:
{ "name": "Alice", "age": 25, "city": "New York"}4.3 - json.dumps() với sort_keys
Phần tiêu đề “4.3 - json.dumps() với sort_keys”import json
person = { "name": "Alice", "age": 25, "city": "New York"}
# Sắp xếp keys theo alphabetjson_string = json.dumps(person, indent=4, sort_keys=True)print(json_string)4.4 - json.dump() - Ghi trực tiếp vào file
Phần tiêu đề “4.4 - json.dump() - Ghi trực tiếp vào file”import json
person = { "name": "Alice", "age": 25, "city": "New York"}
# Ghi vào filewith open('person.json', 'w', encoding='utf-8') as file: json.dump(person, file, indent=4, ensure_ascii=False)Lưu ý: ensure_ascii=False để hiển thị ký tự tiếng Việt đúng
5. Chuyển đổi JSON → Python (Deserialization)
Phần tiêu đề “5. Chuyển đổi JSON → Python (Deserialization)”5.1 - json.loads() - Chuyển string thành object
Phần tiêu đề “5.1 - json.loads() - Chuyển string thành object”import json
# JSON stringjson_string = '{"name": "Alice", "age": 25, "city": "New York"}'
# Chuyển thành Python dictperson = json.loads(json_string)print(person)print(type(person)) # <class 'dict'>
# Truy cập dữ liệuprint(person['name']) # Aliceprint(person['age']) # 255.2 - json.load() - Đọc từ file
Phần tiêu đề “5.2 - json.load() - Đọc từ file”import json
# Đọc file JSONwith open('person.json', 'r', encoding='utf-8') as file: person = json.load(file)
print(person)print(person['name'])6. Làm việc với JSON phức tạp
Phần tiêu đề “6. Làm việc với JSON phức tạp”6.1 - Nested JSON
Phần tiêu đề “6.1 - Nested JSON”import json
data = { "company": "Tech Corp", "employees": [ { "name": "Alice", "age": 25, "skills": ["Python", "JavaScript"] }, { "name": "Bob", "age": 30, "skills": ["Java", "C++"] } ], "location": { "city": "New York", "country": "USA" }}
# Ghi vào filewith open('company.json', 'w', encoding='utf-8') as file: json.dump(data, file, indent=4)
# Đọc và truy cập nested datawith open('company.json', 'r', encoding='utf-8') as file: company = json.load(file)
print(company['employees'][0]['name']) # Aliceprint(company['location']['city']) # New York6.2 - List of objects
Phần tiêu đề “6.2 - List of objects”import json
students = [ {"name": "Alice", "age": 20, "grade": "A"}, {"name": "Bob", "age": 22, "grade": "B"}, {"name": "Charlie", "age": 21, "grade": "A"}]
# Ghi list vào JSONwith open('students.json', 'w', encoding='utf-8') as file: json.dump(students, file, indent=4)
# Đọc và xử lýwith open('students.json', 'r', encoding='utf-8') as file: students = json.load(file)
for student in students: print(f"{student['name']}: {student['grade']}")7. Xử lý ký tự đặc biệt
Phần tiêu đề “7. Xử lý ký tự đặc biệt”7.1 - Tiếng Việt và Unicode
Phần tiêu đề “7.1 - Tiếng Việt và Unicode”import json
data = { "name": "Nguyễn Văn A", "city": "Hà Nội", "message": "Xin chào"}
# ensure_ascii=False để giữ ký tự Unicodejson_string = json.dumps(data, indent=4, ensure_ascii=False)print(json_string)
# Ghi file với encoding utf-8with open('vietnamese.json', 'w', encoding='utf-8') as file: json.dump(data, file, indent=4, ensure_ascii=False)8. Xử lý lỗi
Phần tiêu đề “8. Xử lý lỗi”8.1 - JSON không hợp lệ
Phần tiêu đề “8.1 - JSON không hợp lệ”import json
invalid_json = '{"name": "Alice", "age": 25,}' # Dấu phẩy thừa
try: data = json.loads(invalid_json)except json.JSONDecodeError as e: print(f"Lỗi JSON: {e}") # Lỗi JSON: Expecting property name enclosed in double quotes: line 1 column 28 (char 27)8.2 - File không tồn tại
Phần tiêu đề “8.2 - File không tồn tại”import json
try: with open('nonexistent.json', 'r') as file: data = json.load(file)except FileNotFoundError: print("File không tồn tại!")except json.JSONDecodeError: print("File JSON không hợp lệ!")9. Làm việc với API
Phần tiêu đề “9. Làm việc với API”9.1 - Đọc JSON từ API (giả lập)
Phần tiêu đề “9.1 - Đọc JSON từ API (giả lập)”import json
# Giả sử nhận được JSON từ APIapi_response = '''{ "status": "success", "data": { "users": [ {"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"} ] }}'''
# Parse JSONresponse = json.loads(api_response)
if response['status'] == 'success': users = response['data']['users'] for user in users: print(f"ID: {user['id']}, Name: {user['name']}")10. JSON với Custom Objects
Phần tiêu đề “10. JSON với Custom Objects”10.1 - Serialize custom class
Phần tiêu đề “10.1 - Serialize custom class”import json
class Person: def __init__(self, name, age): self.name = name self.age = age
def person_to_dict(person): return { 'name': person.name, 'age': person.age }
# Tạo objectperson = Person("Alice", 25)
# Chuyển thành JSONjson_string = json.dumps(person, default=person_to_dict, indent=4)print(json_string)10.2 - Deserialize to custom class
Phần tiêu đề “10.2 - Deserialize to custom class”import json
class Person: def __init__(self, name, age): self.name = name self.age = age
def dict_to_person(data): return Person(data['name'], data['age'])
# JSON stringjson_string = '{"name": "Alice", "age": 25}'
# Parse và tạo objectdata = json.loads(json_string)person = dict_to_person(data)
print(f"{person.name}, {person.age} years old")11. Thao tác với JSON
Phần tiêu đề “11. Thao tác với JSON”11.1 - Thêm dữ liệu vào JSON file
Phần tiêu đề “11.1 - Thêm dữ liệu vào JSON file”import json
# Đọc file hiện tạiwith open('students.json', 'r', encoding='utf-8') as file: students = json.load(file)
# Thêm student mớinew_student = {"name": "David", "age": 23, "grade": "B"}students.append(new_student)
# Ghi lại filewith open('students.json', 'w', encoding='utf-8') as file: json.dump(students, file, indent=4, ensure_ascii=False)11.2 - Cập nhật dữ liệu
Phần tiêu đề “11.2 - Cập nhật dữ liệu”import json
# Đọc filewith open('person.json', 'r', encoding='utf-8') as file: person = json.load(file)
# Cập nhậtperson['age'] = 26
# Ghi lạiwith open('person.json', 'w', encoding='utf-8') as file: json.dump(person, file, indent=4)11.3 - Xoá dữ liệu
Phần tiêu đề “11.3 - Xoá dữ liệu”import json
# Đọc filewith open('person.json', 'r', encoding='utf-8') as file: person = json.load(file)
# Xoá keyif 'email' in person: del person['email']
# Ghi lạiwith open('person.json', 'w', encoding='utf-8') as file: json.dump(person, file, indent=4)12. So sánh JSON vs CSV
Phần tiêu đề “12. So sánh JSON vs CSV”| Feature | JSON | CSV |
|---|---|---|
| Cấu trúc | Phân cấp (nested) | Phẳng (flat) |
| Kiểu dữ liệu | Đa dạng | Chủ yếu text |
| Kích thước | Lớn hơn | Nhỏ hơn |
| Dễ đọc | Trung bình | Cao |
| Sử dụng | API, Config | Data export, Excel |
13. Tips và Best Practices
Phần tiêu đề “13. Tips và Best Practices”1. Luôn dùng encoding utf-8
Phần tiêu đề “1. Luôn dùng encoding utf-8”# ✅ TỐTwith open('data.json', 'r', encoding='utf-8') as file: data = json.load(file)2. Xử lý exception
Phần tiêu đề “2. Xử lý exception”try: with open('data.json', 'r', encoding='utf-8') as file: data = json.load(file)except (FileNotFoundError, json.JSONDecodeError) as e: print(f"Error: {e}")3. Dùng indent cho dễ đọc
Phần tiêu đề “3. Dùng indent cho dễ đọc”# ✅ TỐT - Dễ đọcjson.dump(data, file, indent=4)4. ensure_ascii=False cho tiếng Việt
Phần tiêu đề “4. ensure_ascii=False cho tiếng Việt”json.dump(data, file, indent=4, ensure_ascii=False)14. Lỗi thường gặp
Phần tiêu đề “14. Lỗi thường gặp”Lỗi 1: Quên encoding
Phần tiêu đề “Lỗi 1: Quên encoding”# ❌ SAI - Lỗi với tiếng Việtwith open('data.json', 'r') as file: data = json.load(file)
# ✅ ĐÚNGwith open('data.json', 'r', encoding='utf-8') as file: data = json.load(file)Lỗi 2: Nhầm dumps và dump
Phần tiêu đề “Lỗi 2: Nhầm dumps và dump”# ❌ SAIjson.dumps(data, file) # dumps không nhận file
# ✅ ĐÚNGjson.dump(data, file) # dump ghi vào fileLỗi 3: JSON không hợp lệ
Phần tiêu đề “Lỗi 3: JSON không hợp lệ”# ❌ SAI - Single quotes không hợp lệ trong JSONinvalid = "{'name': 'Alice'}"
# ✅ ĐÚNG - Phải dùng double quotesvalid = '{"name": "Alice"}'