Courses
JSON (JavaScript Object Notation) là một định dạng trao đổi dữ liệu nhẹ, đã trở thành lựa chọn phổ biến để trao đổi dữ liệu trong nhiều ngôn ngữ lập trình, bao gồm cả Python. Nhờ cú pháp đơn giản và khả năng biểu diễn các cấu trúc dữ liệu phức tạp, JSON đã trở thành một phần không thể thiếu của phát triển web hiện đại, cung cấp sức mạnh cho mọi thứ từ API đến các ứng dụng web phía client.
Trong hướng dẫn này, tôi sẽ khám phá những điều cơ bản khi làm việc với JSON trong Python, bao gồm tuần tự hóa, giải tuần tự, đọc và ghi tệp JSON, định dạng và hơn thế nữa. Kết thúc hướng dẫn, bạn sẽ:
- Hiểu JSON cùng các ưu và nhược điểm của nó
- Xác định các trường hợp sử dụng JSON và so sánh với những lựa chọn thay thế phổ biến
- Tuần tự hóa và giải tuần tự dữ liệu JSON hiệu quả trong Python
- Làm việc với dữ liệu JSON trong ngôn ngữ lập trình Python
- Định dạng dữ liệu JSON trong Python bằng thư viện `json`
- Tối ưu hiệu năng khi làm việc với dữ liệu JSON
- Quản lý dữ liệu JSON trong phát triển API.
JSON là gì?
JSON (JavaScript Object Notation) là một định dạng trao đổi dữ liệu nhẹ, độc lập với ngôn ngữ, được áp dụng rộng rãi và hỗ trợ bởi nhiều ngôn ngữ lập trình và framework. Đây là lựa chọn tốt cho trao đổi dữ liệu khi cần một định dạng đơn giản, dễ đọc, hỗ trợ các cấu trúc dữ liệu phức tạp và có thể dễ dàng chia sẻ giữa các chương trình máy tính khác nhau.
Trường hợp sử dụng hoàn hảo cho JSON là khi cần trao đổi dữ liệu giữa các ứng dụng dựa trên web, chẳng hạn khi bạn điền một biểu mẫu trên trang web và thông tin được gửi đến máy chủ để xử lý.
JSON lý tưởng cho kịch bản này vì nó là định dạng nhẹ và hiệu quả, yêu cầu ít băng thông và dung lượng lưu trữ hơn so với các định dạng khác như XML. Ngoài ra, JSON hỗ trợ các cấu trúc dữ liệu phức tạp như đối tượng lồng nhau và mảng, giúp dễ dàng biểu diễn và trao đổi dữ liệu có cấu trúc giữa các hệ thống khác nhau. Một vài trường hợp sử dụng khác cho định dạng JSON gồm:
- Giao diện lập trình ứng dụng (API). JSON thường được dùng để xây dựng API (Application Programming Interfaces) cho phép các hệ thống và ứng dụng khác nhau giao tiếp với nhau. Ví dụ, nhiều API dựa trên web sử dụng JSON làm định dạng dữ liệu để trao đổi giữa các ứng dụng, giúp dễ dàng tích hợp với nhiều ngôn ngữ và nền tảng.
- Tệp cấu hình. JSON cung cấp định dạng đơn giản và dễ đọc để lưu trữ và truy xuất dữ liệu cấu hình. Điều này có thể bao gồm các thiết lập cho ứng dụng, như bố cục giao diện người dùng hoặc tùy chọn của người dùng.
- IoT (Internet vạn vật). Thiết bị IoT thường tạo ra lượng dữ liệu lớn, có thể được lưu trữ và truyền giữa các cảm biến và thiết bị khác hiệu quả hơn nhờ JSON.

Ví dụ về dữ liệu JSON
python_obj = {
"name": "John Doe",
"age": 30,
"email": "[email protected]",
"is_employee": True,
"hobbies": [
"reading",
"playing soccer",
"traveling"
],
"address": {
"street": "123 Main Street",
"city": "New York",
"state": "NY",
"zip": "10001"
}
}
print(python_obj)
Trong ví dụ này, chúng ta có một đối tượng JSON biểu diễn một người. Đối tượng có một số thuộc tính: name, age, email và is_employee. Thuộc tính hobbies là một mảng chứa ba chuỗi. Thuộc tính address là một đối tượng với một số thuộc tính riêng như street, city, state và zip.
Lưu ý rằng dữ liệu JSON thường được định dạng dưới dạng một chuỗi các cặp khóa-giá trị, với khóa là một chuỗi và giá trị có thể là nhiều kiểu như chuỗi, số, boolean, mảng hoặc đối tượng.
Ưu và nhược điểm khi sử dụng JSON
Dưới đây, chúng tôi chọn lọc một số điểm tích cực và hạn chế khi dùng JSON.
Ưu điểm khi làm việc với tệp JSON:
Một số lợi thế chính của JSON bao gồm việc nó:
- Nhẹ và dễ đọc. Các tệp JSON dễ đọc và dễ hiểu, ngay cả với người không chuyên kỹ thuật. Chúng cũng nhẹ, nghĩa là có thể dễ dàng truyền qua internet.
- Tương tác tốt: Các tệp JSON có khả năng tương tác, tức là có thể dễ dàng trao đổi giữa các hệ thống và nền tảng khác nhau. Điều này là do JSON là một định dạng tiêu chuẩn được hỗ trợ rộng rãi, và nhiều ứng dụng, dịch vụ dùng JSON để trao đổi dữ liệu. Nhờ đó, làm việc với tệp JSON có thể giúp dễ dàng tích hợp các phần của một hệ thống hoặc chia sẻ dữ liệu giữa các ứng dụng.
- Dễ xác thực: Các tệp JSON có thể dễ dàng được xác thực dựa trên một schema để đảm bảo tuân theo cấu trúc hoặc bộ quy tắc cụ thể. Điều này giúp phát hiện sớm lỗi và sự không nhất quán trong dữ liệu, tiết kiệm thời gian và ngăn ngừa sự cố về sau. Schema JSON cũng có thể được dùng để tự động tạo tài liệu cho dữ liệu lưu trong tệp JSON.
Nhược điểm khi làm việc với tệp JSON:
- Hỗ trợ hạn chế cho cấu trúc dữ liệu phức tạp: Mặc dù các tệp JSON hỗ trợ nhiều kiểu dữ liệu, chúng không phù hợp để lưu trữ các cấu trúc phức tạp như đồ thị hoặc cây. Điều này có thể gây khó khăn khi làm việc với một số loại dữ liệu bằng tệp JSON.
- Không áp đặt schema: Các tệp JSON không áp đặt bất kỳ schema nào, có nghĩa là có thể lưu dữ liệu không nhất quán hoặc không hợp lệ trong tệp JSON. Điều này có thể dẫn đến lỗi và bug trong các ứng dụng phụ thuộc vào dữ liệu trong tệp.
- Khả năng truy vấn và lập chỉ mục hạn chế: Các tệp JSON không cung cấp mức độ truy vấn và lập chỉ mục như cơ sở dữ liệu truyền thống. Điều này khiến việc thực hiện các tìm kiếm phức tạp hoặc truy xuất tập con dữ liệu cụ thể từ một tệp JSON lớn trở nên khó khăn.
Các lựa chọn thay thế hàng đầu cho JSON để trao đổi dữ liệu hiệu quả
Có một số lựa chọn thay thế JSON có thể dùng cho trao đổi hoặc lưu trữ dữ liệu, mỗi loại có điểm mạnh và yếu riêng. Một số lựa chọn phổ biến gồm:
- XML (Extensible Markup Language). XML là ngôn ngữ đánh dấu dùng thẻ để định nghĩa phần tử và thuộc tính để mô tả dữ liệu. Nó dài dòng hơn JSON, nhưng có hỗ trợ mạnh cho xác thực schema và cấu trúc tài liệu.
- YAML (Yet Another Markup Language). YAML là định dạng tuần tự hóa dữ liệu thân thiện với con người, được thiết kế để dễ đọc và viết. Nó ngắn gọn hơn XML và hỗ trợ các kiểu dữ liệu phức tạp và chú thích.
- MessagePack. MessagePack là định dạng tuần tự hóa nhị phân được thiết kế nhỏ gọn và hiệu quả hơn JSON. Nó hỗ trợ các kiểu dữ liệu phức tạp và lý tưởng để truyền dữ liệu qua mạng băng thông thấp.
- Protocol Buffers. Protocol Buffers là định dạng tuần tự hóa nhị phân do Google phát triển. Nó được thiết kế rất hiệu quả và có hỗ trợ mạnh cho xác thực schema, phù hợp cho các hệ thống phân tán quy mô lớn.
- BSON (Binary JSON). BSON là định dạng tuần tự hóa nhị phân mở rộng JSON với các kiểu dữ liệu bổ sung và tối ưu hóa hiệu suất. Nó được thiết kế để lưu trữ và truyền dữ liệu hiệu quả trong cơ sở dữ liệu MongoDB.
Việc chọn định dạng trao đổi dữ liệu phụ thuộc vào trường hợp sử dụng cụ thể và yêu cầu của ứng dụng. JSON vẫn là lựa chọn phổ biến nhờ sự đơn giản, linh hoạt và mức độ phổ biến rộng rãi, nhưng các định dạng khác như XML, YAML, MessagePack, Protocol Buffers và BSON có thể phù hợp hơn cho một số trường hợp.
Thư viện Python để làm việc với dữ liệu JSON
Có một vài gói Python phổ biến bạn có thể dùng để làm việc với tệp JSON:
- json. Đây là gói tích hợp sẵn trong Python, cung cấp các phương thức để mã hóa và giải mã dữ liệu JSON.
- simplejson. Gói này cung cấp bộ mã hóa và giải mã JSON nhanh với hỗ trợ cho các kiểu dữ liệu đặc thù Python.
- ujson. Gói này là bộ mã hóa và giải mã JSON siêu nhanh cho Python.
- jsonschema. Gói này cung cấp cách để xác thực dữ liệu JSON theo một schema xác định.
Tuần tự hóa và giải tuần tự JSON
Tuần tự hóa và giải tuần tự JSON là quá trình chuyển đổi dữ liệu JSON sang và từ các định dạng khác, như đối tượng hoặc chuỗi Python, để truyền hoặc lưu trữ dữ liệu.
Tuần tự hóa là quá trình chuyển một đối tượng hoặc cấu trúc dữ liệu thành chuỗi JSON. Quá trình này cần thiết để truyền hoặc lưu trữ dữ liệu ở định dạng có thể được các hệ thống hoặc chương trình khác đọc. Tuần tự hóa JSON là kỹ thuật phổ biến trong phát triển web, nơi dữ liệu thường được truyền giữa các hệ thống hoặc ứng dụng khác nhau.
Ngược lại, giải tuần tự là quá trình chuyển chuỗi JSON trở lại thành một đối tượng hoặc cấu trúc dữ liệu. Quá trình này cần thiết để sử dụng dữ liệu trong chương trình hoặc hệ thống. Giải tuần tự JSON thường được dùng trong phát triển web để phân tích dữ liệu nhận từ API hoặc nguồn khác.
Tuần tự hóa và giải tuần tự JSON là các kỹ thuật quan trọng để làm việc với dữ liệu JSON trong nhiều bối cảnh, từ phát triển web đến phân tích dữ liệu và hơn thế nữa. Nhiều ngôn ngữ lập trình cung cấp thư viện hoặc gói tích hợp sẵn để việc tuần tự hóa và giải tuần tự trở nên dễ dàng và hiệu quả.
Dưới đây là một số hàm phổ biến từ thư viện json dùng cho tuần tự hóa và giải tuần tự.
1. json.dumps()
Hàm này dùng để tuần tự hóa một đối tượng Python thành chuỗi JSON. Hàm dumps() nhận một đối số là đối tượng Python và trả về chuỗi JSON. Ví dụ:
import json
# Python object to JSON string
python_obj = {'name': 'John', 'age': 30}
json_string = json.dumps(python_obj)
print(json_string)
# Expected output: {"name": "John", "age": 30}
2. json.loads()
Hàm này dùng để phân tích một chuỗi JSON thành đối tượng Python. Hàm loads() nhận một đối số là chuỗi JSON và trả về một đối tượng Python. Ví dụ:
import json
# JSON string to Python object
json_string = '{"name": "John", "age": 30}'
python_obj = json.loads(json_string)
print(python_obj)
# Expected output: {'name': 'John', 'age': 30}
3. json.dump()
Hàm này dùng để tuần tự hóa một đối tượng Python và ghi nó vào tệp JSON. Hàm dump() nhận hai đối số là đối tượng Python và đối tượng tệp. Ví dụ:
import json
# serialize Python object and write to JSON file
python_obj = {'name': 'John', 'age': 30}
with open('data.json', 'w') as file:
json.dump(python_obj, file)
# No expected output
4. json.load()
Hàm này dùng để đọc một tệp JSON và phân tích nội dung của nó thành đối tượng Python. Hàm load() nhận một đối số là đối tượng tệp và trả về một đối tượng Python. Ví dụ:
import json
# read JSON file and parse contents
with open('data.json', 'r') as file:
python_obj = json.load(file)
print(python_obj)
# Expected output: {'name': 'John', 'age': 30}
Python và JSON có các kiểu dữ liệu khác nhau, trong đó Python cung cấp phạm vi kiểu dữ liệu rộng hơn JSON. Trong khi Python có thể lưu trữ các cấu trúc dữ liệu phức tạp như set và dict, JSON bị giới hạn ở chuỗi, số, boolean, mảng và đối tượng. Hãy xem một số khác biệt:
|
Python |
JSON |
|
dict |
Object |
|
list |
Array |
|
tuple |
Array |
|
str |
String |
|
int |
Number |
|
float |
Number |
|
True |
true |
|
False |
false |
|
None |
null |
Chuyển list Python sang JSON
Để chuyển một list Python sang định dạng JSON, bạn có thể dùng phương thức json.dumps() từ thư viện json.
import json
my_list = [1, 2, 3, "four", "five"]
json_string = json.dumps(my_list)
print(json_string)
# Expected output: [1, 2, 3, "four", "five"]
Trong ví dụ này, chúng ta có một list tên là my_list với sự kết hợp giữa số nguyên và chuỗi. Sau đó, chúng ta dùng phương thức json.dumps() để chuyển list thành chuỗi định dạng JSON và lưu vào biến json_string.
Định dạng dữ liệu JSON
Trong Python, hàm json.dumps() cung cấp các tùy chọn để định dạng và sắp xếp đầu ra JSON. Dưới đây là vài tùy chọn phổ biến:
1. Indent
Tùy chọn này chỉ định số lượng khoảng trắng dùng để thụt dòng trong chuỗi JSON đầu ra. Ví dụ:
import json
data = {
"name": "John",
"age": 30,
"city": "New York"
}
json_data = json.dumps(data, indent=2)
print(json_data)
# Expected output: a JSON formatted string with an indentation of 2 spaces for each level of nesting:
# {
# "name": "John",
# "age": 30,
# "city": "New York"
# }
2. Sort_keys
Tùy chọn này chỉ định xem các khóa trong chuỗi JSON đầu ra có được sắp xếp theo thứ tự bảng chữ cái hay không. Ví dụ:
import json
data = {
"name": "John",
"age": 30,
"city": "New York"
}
json_data = json.dumps(data, sort_keys=True)
print(json_data)
# Expected output: {"age": 30, "city": "New York", "name": "John"}
3. Separators
Tùy chọn này cho phép bạn chỉ định các ký tự phân tách dùng trong chuỗi JSON đầu ra. Tham số separators nhận một bộ hai chuỗi, trong đó chuỗi thứ nhất là dấu phân tách giữa các cặp khóa-giá trị của đối tượng JSON, và chuỗi thứ hai là dấu phân tách giữa các phần tử trong mảng JSON. Ví dụ:
import json
data = {
"name": "John",
"age": 30,
"city": "New York"
}
json_data = json.dumps(data, separators=(",", ":"))
print(json_data)
# Expected output: a JSON formatted string with a comma separator between key-value pairs and a colon separator between keys and values:
# {"name":"John","age":30,"city":"New York"}
Ví dụ Python - Dữ liệu JSON trong API
import requests
import json
url = "https://jsonplaceholder.typicode.com/posts"
response = requests.get(url)
if response.status_code == 200:
data = json.loads(response.text)
print(data)
else:
print(f"Error retrieving data, status code: {response.status_code}")
# Expected output: a JSON object as the response of the request
ĐẦU RA ĐÃ ĐỊNH DẠNG:

Đoạn mã này sử dụng thư viện requests và json trong Python để gửi yêu cầu tới URL "https://jsonplaceholder.typicode.com/posts" và truy xuất dữ liệu. Dòng requests.get(url) thực hiện yêu cầu và lưu phản hồi vào biến response.
Dòng if response.status_code == 200: kiểm tra xem mã trạng thái phản hồi có phải 200 hay không, nghĩa là yêu cầu thành công. Nếu yêu cầu thành công, mã sẽ nạp nội dung phản hồi vào một dict Python bằng phương thức json.loads() và lưu trong biến data.
Nếu bạn muốn tìm hiểu thêm về chủ đề này, hãy xem hướng dẫn của chúng tôi về Web API, Python Requests & Thực hiện HTTP Request trong Python.
Tối ưu hiệu năng JSON trong Python
Khi làm việc với lượng dữ liệu JSON lớn trong Python, việc tối ưu hiệu năng mã của bạn rất quan trọng để đảm bảo chương trình chạy hiệu quả. Dưới đây là một số mẹo tối ưu:
- Dùng thư viện
cjsonhoặcujson. Những thư viện này nhanh hơn thư viện JSON tiêu chuẩn trong Python và có thể cải thiện đáng kể hiệu năng tuần tự hóa và giải tuần tự JSON. - Tránh chuyển đổi không cần thiết. Việc chuyển qua lại giữa đối tượng Python và dữ liệu JSON có thể tốn kém về hiệu năng. Nếu có thể, hãy cố gắng làm việc trực tiếp với dữ liệu JSON và tránh các chuyển đổi không cần thiết.
- Dùng generator cho dữ liệu JSON lớn. Khi làm việc với lượng lớn dữ liệu JSON, sử dụng generator có thể giúp giảm sử dụng bộ nhớ và cải thiện hiệu năng.
- Giảm chi phí mạng. Khi truyền dữ liệu JSON qua mạng, giảm lượng dữ liệu truyền đi có thể cải thiện hiệu năng. Hãy dùng kỹ thuật nén như gzip để giảm kích thước dữ liệu JSON trước khi truyền qua mạng.
- Sử dụng bộ nhớ đệm (caching). Nếu bạn thường xuyên truy cập cùng một dữ liệu JSON, lưu đệm dữ liệu có thể cải thiện hiệu năng bằng cách giảm số lượng yêu cầu tải dữ liệu.
- Tối ưu cấu trúc dữ liệu: Cấu trúc của dữ liệu JSON cũng ảnh hưởng đến hiệu năng. Sử dụng cấu trúc đơn giản, phẳng thường hiệu quả hơn cấu trúc phức tạp, lồng nhau.
Hạn chế của định dạng JSON
Mặc dù JSON là định dạng phổ biến để trao đổi dữ liệu trong nhiều ứng dụng, có một số hạn chế triển khai cần lưu ý:
- Thiếu hỗ trợ cho một số kiểu dữ liệu. JSON hỗ trợ hạn chế cho một số kiểu dữ liệu như dữ liệu nhị phân, ngày và thời gian. Dù có thể có cách biểu diễn chúng trong JSON, điều này làm quá trình tuần tự hóa và giải tuần tự phức tạp hơn.
- Không hỗ trợ chú thích. Không giống các định dạng khác như YAML và XML, JSON không hỗ trợ chú thích. Điều này khiến việc thêm ghi chú vào dữ liệu JSON để cung cấp ngữ cảnh hoặc tài liệu trở nên khó khăn hơn.
- Tính linh hoạt hạn chế cho mở rộng. Mặc dù JSON hỗ trợ mở rộng thông qua các thuộc tính tùy chỉnh hoặc thuộc tính $schema, định dạng này không linh hoạt cho mở rộng bằng các định dạng khác như XML hoặc YAML.
- Không có tiêu chuẩn để bảo toàn thứ tự khóa. JSON không có cách tiêu chuẩn để bảo toàn thứ tự các khóa trong một đối tượng, khiến việc so sánh hoặc hợp nhất các đối tượng JSON khó khăn hơn.
- Hỗ trợ hạn chế cho tham chiếu vòng. JSON hỗ trợ hạn chế cho các tham chiếu vòng, nơi một đối tượng tham chiếu lại chính nó. Điều này khiến việc biểu diễn một số cấu trúc dữ liệu trong JSON trở nên khó khăn.
Điều quan trọng là cần nhận thức về các hạn chế triển khai này khi làm việc với dữ liệu JSON để đảm bảo định dạng phù hợp với nhu cầu của bạn và tránh các vấn đề tiềm ẩn về tuần tự hóa, giải tuần tự và biểu diễn dữ liệu.
Kết luận
JSON là một định dạng linh hoạt và được sử dụng rộng rãi để trao đổi dữ liệu trong phát triển web hiện đại, và Python cung cấp một bộ công cụ mạnh mẽ để làm việc với dữ liệu JSON. Dù bạn đang xây dựng API hay làm việc với các ứng dụng web phía client, hiểu những điều cơ bản về JSON trong Python là kỹ năng thiết yếu cho mọi lập trình viên hiện đại. Bằng cách nắm vững các kỹ thuật được trình bày trong hướng dẫn này, bạn sẽ sớm làm chủ việc xử lý dữ liệu JSON trong Python và xây dựng các ứng dụng vững chắc, có khả năng mở rộng, tận dụng sức mạnh của định dạng trao đổi dữ liệu mạnh mẽ này.
Nếu bạn muốn học cách xây dựng pipeline để nhập dữ liệu lưu ở các định dạng phổ biến, hãy xem khóa Streamlined Data Ingestion with pandas. Bạn sẽ dùng pandas, một thư viện Python lớn cho phân tích, để lấy dữ liệu từ nhiều nguồn, bao gồm bảng tính phản hồi khảo sát, cơ sở dữ liệu yêu cầu dịch vụ công và API của một trang đánh giá phổ biến.
Câu hỏi thường gặp
Làm thế nào để xử lý các tệp JSON quá lớn không vừa bộ nhớ?
Để làm việc với các tệp JSON quá lớn không vừa bộ nhớ, bạn có thể xử lý dữ liệu theo từng phần bằng thư viện ijson của Python hoặc đọc tệp theo từng dòng nếu JSON được cấu trúc như một chuỗi các đối tượng nhỏ hơn. Ví dụ:
import ijson
with open('large_file.json', 'r') as file:
for item in ijson.items(file, 'item'):
print(item) # Process each JSON item individuallyLàm thế nào để hợp nhất hai đối tượng JSON trong Python?
Bạn có thể hợp nhất hai đối tượng JSON bằng cách trước tiên giải tuần tự chúng thành các dictionary của Python, sau đó cập nhật một dictionary bằng nội dung của dictionary kia:
import json
json1 = '{"name": "Alice", "age": 25}'
json2 = '{"city": "New York", "hobbies": ["reading", "cycling"]}'
dict1 = json.loads(json1)
dict2 = json.loads(json2)
dict1.update(dict2)
merged_json = json.dumps(dict1)
print(merged_json)
# Output: {"name": "Alice", "age": 25, "city": "New York", "hobbies": ["reading", "cycling"]}JSON có thể bao gồm chú thích không và xử lý chúng trong Python như thế nào?
JSON không hỗ trợ chú thích một cách nguyên bản, nhưng nếu bạn làm việc với tệp JSON không chuẩn có chứa chú thích (ví dụ dùng // hoặc /* */), bạn có thể tiền xử lý tệp để loại bỏ chúng trước khi phân tích. Ví dụ:
import json
import re
with open('file_with_comments.json', 'r') as file:
content = file.read()
# Remove comments
content = re.sub(r'//.*?$|/\*.*?\*/', '', content, flags=re.DOTALL | re.MULTILINE)
data = json.loads(content)
print(data)