تحويل CSV إلى JSON بـ Python — دليل json.dumps()
استخدم محوّل CSV إلى JSON المجاني مباشرةً في متصفحك — لا حاجة للتثبيت.
جرّب محوّل CSV إلى JSON أونلاين ←تظهر ملفات CSV في كل مكان — تقارير مُصدَّرة، ومقتطفات قواعد بيانات، وسجلات مستخرجة — وعاجلاً أم آجلاً ستحتاج إلى تحويل ملف CSV إلى JSON في Python. تتولى المكتبة القياسية هذه المهمة بوحدتين: csv.DictReader تُحوّل كل صف إلى قاموس Python، و json.dumps() تُسلسل تلك القواميس إلى سلسلة JSON. للتحويل السريع دون كتابة كود، يُنجز محوّل CSV إلى JSON المهمة فوراً في المتصفح. يغطي هذا الدليل المسار البرمجي الكامل: json.dump() مقابل json.dumps()، وكتابة JSON إلى ملفات، وتسلسل dataclass، وتحويل الأنواع من قيم CSV، ومعالجة datetime وDecimal، والبدائل عالية الأداء مثل orjson. جميع الأمثلة مكتوبة لـ Python 3.10+.
- ✓ينتج csv.DictReader قائمة من القواميس — سلسلها كاملةً بـ json.dump(rows, f, indent=2) لكتابة ملف JSON.
- ✓json.dump() يكتب مباشرةً إلى كائن الملف. json.dumps() يُعيد سلسلة نصية. اختر الأنسب لتجنّب نسخة وسيطة غير ضرورية.
- ✓قيم CSV سلاسل نصية دائماً. حوّل الأعمدة الرقمية صراحةً (int() وfloat()) قبل التسلسل إلى JSON.
- ✓مرّر ensure_ascii=False إلى json.dumps() للحفاظ على محارف Unicode — الأسماء العربية ونصوص CJK — في الناتج.
- ✓لمعالجة datetime وUUID وDecimal من CSV، استخدم المعامل default= مع دالة احتياطية مخصصة.
[
{
"order_id": "ORD-7291",
"product": "Wireless Keyboard",
"quantity": "2",
"price": "49.99"
},
{
"order_id": "ORD-7292",
"product": "USB-C Hub",
"quantity": "1",
"price": "34.50"
}
]order_id,product,quantity,price ORD-7291,Wireless Keyboard,2,49.99 ORD-7292,USB-C Hub,1,34.50
"2"، "49.99") في الناتج الخام. لا يوجد نظام أنواع في CSV — كل قيمة هي سلسلة نصية. سنتناول كيفية تصحيح ذلك في قسم تحويل الأنواع أدناه.json.dumps() — تسلسل قاموس Python إلى سلسلة JSON
تأتي وحدة json مدمجةً مع كل تثبيت Python — لا حاجة إلى pip install. json.dumps(obj) تأخذ كائن Python (قاموس أو قائمة أو سلسلة أو رقم أو قيمة منطقية أو None) وتُعيد str تحتوي على JSON صحيح. يبدو القاموس في Python مشابهاً لكائن JSON، لكنهما مختلفان جوهرياً: القاموس هو بنية بيانات Python في الذاكرة، وسلسلة JSON هي نص متسلسَل. استدعاء json.dumps() يتولى هذا التحويل.
مثال بسيط — صف CSV واحد إلى JSON
import json
# A single CSV row represented as a Python dict
server_entry = {
"hostname": "web-prod-03",
"ip_address": "10.0.12.47",
"port": 8080,
"region": "eu-west-1"
}
# Convert dict to JSON string
json_string = json.dumps(server_entry)
print(json_string)
# {"hostname": "web-prod-03", "ip_address": "10.0.12.47", "port": 8080, "region": "eu-west-1"}
print(type(json_string))
# <class 'str'>ينتج هذا JSON مضغوطاً في سطر واحد — جيد للحمولات والتخزين، لكنه صعب القراءة. أضف indent=2 للحصول على ناتج مقروء:
import json
server_entry = {
"hostname": "web-prod-03",
"ip_address": "10.0.12.47",
"port": 8080,
"region": "eu-west-1"
}
pretty_json = json.dumps(server_entry, indent=2)
print(pretty_json)
# {
# "hostname": "web-prod-03",
# "ip_address": "10.0.12.47",
# "port": 8080,
# "region": "eu-west-1"
# }معاملان إضافيان أستخدمهما في كل مرة تقريباً: sort_keys=True يرتّب مفاتيح القاموس أبجدياً (مفيد جداً لمقارنة ملفات JSON عبر الإصدارات)، و ensure_ascii=False يحافظ على المحارف غير ASCII بدلاً من تحويلها إلى تسلسلات \uXXXX.
import json
warehouse_record = {
"sku": "WH-9031",
"location": "مستودع دبي 3",
"quantity": 240,
"last_audit": "2026-03-10"
}
output = json.dumps(warehouse_record, indent=2, sort_keys=True, ensure_ascii=False)
print(output)
# {
# "last_audit": "2026-03-10",
# "location": "مستودع دبي 3",
# "quantity": 240,
# "sku": "WH-9031"
# }ملاحظة سريعة حول معامل separators: القيمة الافتراضية هي (", ", ": ") التي تضيف مسافات بعد الفواصل ونقاط النقطتين. للحصول على أكثر ناتج مضغوط ممكن (مفيد عند تضمين JSON في معاملات URL أو تقليص حجم استجابات API)، مرّر separators=(",", ":").
json.dumps() تُحوّل Python True إلى JSON true، وNone إلى null، وتلفّ السلاسل النصية بعلامات اقتباس مزدوجة (Python تسمح بعلامات الاقتباس المفردة، JSON لا تسمح). استخدم دائماً json.dumps() لإنتاج JSON صحيح — لا تعتمد على str() أو repr().من csv.DictReader إلى ملف JSON — خط الأنابيب الكامل
المهمة الأكثر شيوعاً في الواقع العملي هي قراءة ملف CSV كامل وحفظه بتنسيق JSON. إليك السكريبت الكامل في أقل من 10 أسطر. csv.DictReader يُنتج مُكرِّراً من كائنات dict — واحداً لكل صف، مستخدماً السطر الأول كمفاتيح. تغليفه بـ list() يجمع كل الصفوف في قائمة Python، التي تُسلسَل إلى مصفوفة JSON.
import csv
import json
# Step 1: Read CSV rows into a list of dicts
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
rows = list(csv.DictReader(csv_file))
# Step 2: Write the list as a JSON file
with open("inventory.json", "w", encoding="utf-8") as json_file:
json.dump(rows, json_file, indent=2, ensure_ascii=False)
print(f"Converted {len(rows)} rows to inventory.json")استدعاءان لـ open(): أحدهما لقراءة CSV، والآخر لكتابة JSON. هذا كل شيء. لاحظ استخدام json.dump() (بدون حرف s) — تكتب مباشرةً إلى مؤشر الملف. استخدام json.dumps() سيُعيد سلسلة نصية ستحتاج بعدها إلى كتابتها بشكل منفصل بـ f.write(). json.dump() أكثر كفاءةً في استخدام الذاكرة لأنها تبثّ الناتج بدلاً من بناء السلسلة بأكملها في الذاكرة أولاً.
عندما تحتاج إلى JSON كسلسلة نصية بدلاً من ملف — للتضمين في حمولة API، أو الطباعة إلى stdout، أو الإدراج في عمود قاعدة بيانات — انتقل إلى json.dumps():
import csv
import json
with open("sensors.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
# Get the JSON as a string instead of writing to a file
json_payload = json.dumps(rows, indent=2)
print(json_payload)
# [
# {
# "sensor_id": "TMP-4401",
# "location": "المبنى 7 - الطابق 2",
# "reading": "22.4",
# "unit": "celsius"
# },
# ...
# ]صف واحد مقابل مجموعة البيانات كاملة: إذا استدعيت json.dumps(single_dict) تحصل على كائن JSON ({...}). استدع json.dumps(list_of_dicts) وتحصل على مصفوفة JSON ([{...}, {...}]). يعتمد شكل الحاوية الخارجية على ما تمرّره. معظم المستهلكين اللاحقين يتوقعون مصفوفة للبيانات الجدولية.
معالجة القيم غير النصية — تحويل الأنواع من CSV
هذا ما يُفاجئ الجميع في المرة الأولى: csv.DictReader تُعيد كل قيمة كسلسلة نصية. الرقم 42 في ملف CSV يصبح السلسلة "42" في القاموس. إذا سلسلت ذلك مباشرةً بـ json.dumps()، سيحتوي JSON على "quantity": "42" بدلاً من "quantity": 42. واجهات API التي تتحقق من الأنواع سترفض هذا. تحتاج إلى تحويل القيم صراحةً.
import csv
import json
def coerce_types(row: dict) -> dict:
"""Convert string values to appropriate Python types."""
return {
"sensor_id": row["sensor_id"],
"location": row["location"],
"temperature": float(row["temperature"]),
"humidity": float(row["humidity"]),
"battery_pct": int(row["battery_pct"]),
"active": row["active"].lower() == "true",
}
with open("sensor_readings.csv", "r", encoding="utf-8") as f:
rows = [coerce_types(row) for row in csv.DictReader(f)]
print(json.dumps(rows[0], indent=2))
# {
# "sensor_id": "TMP-4401",
# "location": "المبنى 7 - الطابق 2",
# "temperature": 22.4,
# "humidity": 58.3,
# "battery_pct": 87,
# "active": true
# }الآن temperature عدد عشري، وbattery_pct عدد صحيح، وactive قيمة منطقية في ناتج JSON. دالة التحويل خاصة بمخطط CSV — لا توجد طريقة عامة لاستنتاج الأنواع من بيانات CSV، لذا أكتب دالة واحدة لكل تنسيق CSV.
تسلسل الكائنات المخصصة والأنواع غير القياسية
لا تستطيع وحدة json في Python تسلسل datetimeأو UUIDأو Decimalأو الأصناف المخصصة بشكل افتراضي. استدعاء json.dumps() على أي منها يُثير TypeError. هناك نهجان للتعامل مع ذلك.
النهج الأول: معامل default=
مرّر دالة إلى default= تُحوّل الأنواع غير المعروفة إلى شيء قابل للتسلسل. تُستدعى هذه الدالة فقط للكائنات التي لا يعرف مُشفّر JSON كيفية التعامل معها.
import json
from datetime import datetime
from decimal import Decimal
from uuid import UUID
def json_serial(obj):
"""Fallback serializer for non-standard types."""
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, UUID):
return str(obj)
if isinstance(obj, Decimal):
return float(obj)
raise TypeError(f"Type {type(obj).__name__} is not JSON serializable")
transaction = {
"txn_id": UUID("a1b2c3d4-e5f6-7890-abcd-ef1234567890"),
"amount": Decimal("149.99"),
"currency": "EUR",
"processed_at": datetime(2026, 3, 15, 14, 30, 0),
"gateway": "stripe",
}
print(json.dumps(transaction, indent=2, default=json_serial))
# {
# "txn_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
# "amount": 149.99,
# "currency": "EUR",
# "processed_at": "2026-03-15T14:30:00",
# "gateway": "stripe"
# }TypeError في نهاية دالة default= للأنواع غير المعروفة. إذا أعدت None أو تجاهلتها بصمت، ستحصل على null في الناتج دون أي إشارة إلى فقدان البيانات.النهج الثاني: Dataclasses مع asdict()
توفّر Python dataclasses تعريفاً نوعياً صحيحاً لصفوف CSV. استخدم dataclasses.asdict() لتحويل نسخة dataclass إلى قاموس عادي، ثم مرّره إلى json.dumps().
import json
from dataclasses import dataclass, asdict
from datetime import datetime
@dataclass
class ShipmentRecord:
tracking_id: str
origin: str
destination: str
weight_kg: float
shipped_at: datetime
def json_serial(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not serializable: {type(obj).__name__}")
shipment = ShipmentRecord(
tracking_id="SHP-9827",
origin="دبي",
destination="الرياض",
weight_kg=1240.5,
shipped_at=datetime(2026, 3, 12, 8, 0, 0),
)
print(json.dumps(asdict(shipment), indent=2, default=json_serial))
# {
# "tracking_id": "SHP-9827",
# "origin": "دبي",
# "destination": "الرياض",
# "weight_kg": 1240.5,
# "shipped_at": "2026-03-12T08:00:00"
# }asdict() تُحوّل dataclasses المتداخلة بشكل تعاودي إلى قواميس. إذا كانت dataclass تحتوي على قائمة من dataclasses أخرى، يُحوَّل الهيكل بأكمله — دون الحاجة إلى كود إضافي.مرجع معاملات json.dumps()
القائمة الكاملة للمعاملات الاختيارية التي تقبلها json.dumps() و json.dump(). تقبل الدالتان معاملات متطابقة — json.dump() تأخذ معاملاً أولياً إضافياً لكائن الملف.
csv.DictReader — قراءة CSV إلى قواميس Python
csv.DictReader هي النصف الآخر من خط تحويل CSV إلى JSON. تُغلّف كائن ملف وتُنتج كائن dict واحداً لكل صف، مستخدمةً السطر الأول كأسماء حقول. مقارنةً بـ csv.reader (التي تُنتج قوائم عادية)، يمنحك DictReader وصولاً بالاسم إلى الأعمدة — دون مؤشرات غامضة مثل row[3].
import csv
import json
# Tab-separated file from a database export
with open("user_sessions.tsv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f, delimiter="\t")
sessions = list(reader)
print(json.dumps(sessions[:2], indent=2))
# [
# {
# "session_id": "sess_8f2a91bc",
# "user_id": "usr_4421",
# "started_at": "2026-03-15T09:12:00Z",
# "duration_sec": "342",
# "pages_viewed": "7"
# },
# {
# "session_id": "sess_3c7d44ef",
# "user_id": "usr_1187",
# "started_at": "2026-03-15T09:14:22Z",
# "duration_sec": "128",
# "pages_viewed": "3"
# }
# ]csv.DictReader يقرأ الملف بشكل كسول — يُنتج صفوفاً واحدةً تلو الأخرى. استدعاء list(reader) يُحمّل جميع الصفوف إلى الذاكرة. للملفات التي تحتوي على ملايين الصفوف، عالجها بأسلوب البث بدلاً من تجميعها جميعاً.تحويل CSV من ملف ومن استجابة API
سيناريوان في الإنتاج: قراءة ملف CSV من القرص وتحويله، وجلب بيانات CSV من نقطة نهاية API (كثير من خدمات التقارير تُعيد CSV). كلاهما يحتاج إلى معالجة صحيحة للأخطاء.
قراءة ملف CSV ← تحويله ← كتابة JSON
import csv
import json
import sys
def csv_to_json_file(csv_path: str, json_path: str) -> int:
"""Convert a CSV file to JSON. Returns the number of rows written."""
try:
with open(csv_path, "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
except FileNotFoundError:
print(f"Error: {csv_path} not found", file=sys.stderr)
sys.exit(1)
except csv.Error as e:
print(f"CSV parse error in {csv_path}: {e}", file=sys.stderr)
sys.exit(1)
with open(json_path, "w", encoding="utf-8") as f:
json.dump(rows, f, indent=2, ensure_ascii=False)
return len(rows)
count = csv_to_json_file("fleet_vehicles.csv", "fleet_vehicles.json")
print(f"Wrote {count} records to fleet_vehicles.json")جلب CSV من API ← تحليله ← JSON
import csv
import io
import json
import urllib.request
def fetch_csv_as_json(url: str) -> str:
"""Fetch CSV from a URL and return it as a JSON string."""
try:
with urllib.request.urlopen(url, timeout=10) as resp:
raw = resp.read().decode("utf-8")
except urllib.error.URLError as e:
raise RuntimeError(f"Failed to fetch {url}: {e}")
reader = csv.DictReader(io.StringIO(raw))
rows = list(reader)
if not rows:
raise ValueError("CSV response was empty or had no data rows")
return json.dumps(rows, indent=2, ensure_ascii=False)
# Example: export endpoint that returns CSV
try:
result = fetch_csv_as_json("https://reports.internal/api/v2/daily-metrics.csv")
print(result)
except (RuntimeError, ValueError) as e:
print(f"Error: {e}")يستخدم كلا المثالين encoding="utf-8" بشكل صريح عند كل فتح ملف. هذا مهم لملفات CSV التي تحتوي على محارف غير ASCII — الأسماء العربية، والعناوين بمحارف خاصة، ونصوص CJK. بدون ترميز صريح، تعود Python إلى الترميز الافتراضي للنظام، الذي على Windows كثيراً ما يكون cp1252 ويُشوّه المحارف متعددة البايتات بصمت.
التحقق من ناتج JSON بـ json.loads()
بعد تحويل CSV إلى سلسلة JSON، يمكنك التحقق من النتيجة بإعادة تحليلها بـ json.loads(). هذا الاختبار ذهاباً وإياباً يكشف مشكلات الترميز، وتسلسلات الهروب المعطوبة، أو تسلسل السلاسل العرضي الذي قد ينتج JSON غير صحيح. غلّف الاستدعاء في كتلة try/except.
import json
json_string = json.dumps({"order_id": "ORD-7291", "total": 129.99})
# Verify it is valid JSON by parsing it back
try:
parsed = json.loads(json_string)
print(f"Valid JSON with {len(parsed)} keys")
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
# Valid JSON with 2 keysتحويل CSV إلى JSON من سطر الأوامر
تحويلات سريعة من الطرفية — دون الحاجة إلى ملف سكريبت. راية -c في Python تُنفّذ كوداً مباشراً، ويمكنك توجيه الناتج عبر python3 -m json.tool للحصول على ناتج منسّق.
python3 -c " import csv, json, sys rows = list(csv.DictReader(sys.stdin)) json.dump(rows, sys.stdout, indent=2) " < inventory.csv > inventory.json
python3 -c "import csv,json,sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csv | python3 -m json.tool
python3 -c "import csv,json,sys; json.dump(list(csv.DictReader(sys.stdin)),sys.stdout)" < report.csv | jq .
python3 -m json.tool هو مُنسّق JSON المدمج. يقرأ JSON من stdin ويتحقق منه ويطبعه بمسافة بادئة من 4 مسافات. مفيد للتحقق من أن تحويل CSV إلى JSON أنتج ناتجاً صحيحاً. إذا كنت تفضّل مسافة بادئة من مسافتين أو تحتاج إلى تصفية، استخدم jq بدلاً من ذلك.البديل عالي الأداء — orjson
وحدة json المدمجة تؤدي المهمة بكفاءة لمعظم ملفات CSV. لكن إذا كنت تعالج مجموعات بيانات تحتوي على عشرات الآلاف من الصفوف في حلقة، أو كانت واجهة API الخاصة بك تحتاج إلى تسلسل بيانات مشتقة من CSV في كل طلب، orjson أسرع 5–10 أضعاف. مكتوبة بلغة Rust، تُعيد bytes بدلاً من str، وتُسلسل datetime وUUID ومصفوفات numpy بشكل أصلي دون الحاجة إلى دالة default= مخصصة.
pip install orjson
import csv
import orjson
with open("telemetry_events.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
# orjson.dumps() returns bytes, not str
json_bytes = orjson.dumps(rows, option=orjson.OPT_INDENT_2)
with open("telemetry_events.json", "wb") as f: # note: "wb" for bytes
f.write(json_bytes)
print(f"Wrote {len(rows)} events ({len(json_bytes)} bytes)")الواجهة مختلفة قليلاً: orjson.dumps() تُعيد bytes وتستخدم رايات option= بدلاً من المعاملات الاختيارية. افتح الملفات في وضع الكتابة الثنائي ("wb") عند كتابة ناتج orjson. إذا احتجت سلسلة نصية، استدع .decode("utf-8") على النتيجة.
ناتج الطرفية مع تمييز الصياغة — rich
تصبح عملية تصحيح تحويلات CSV إلى JSON في الطرفية أسهل مع الناتج الملوّن. مكتبة rich تعرض JSON مع تمييز الصياغة — المفاتيح والسلاسل والأرقام والقيم المنطقية لكل منها لون مختلف.
pip install rich
import csv
import json
from rich.console import Console
from rich.syntax import Syntax
console = Console()
with open("deployment_log.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
json_output = json.dumps(rows[:3], indent=2, ensure_ascii=False)
syntax = Syntax(json_output, "json", theme="monokai", line_numbers=True)
console.print(syntax)rich تضيف رموز ANSI إلى الناتج. لا تكتب ناتج rich المنسّق إلى ملف أو استجابة API — سيحتوي على رموز تحكم غير مرئية. استخدم rich للعرض في الطرفية فقط.التعامل مع ملفات CSV الكبيرة
تحميل ملف CSV بحجم 500 ميجابايت باستخدام list(csv.DictReader(f)) يُخصّص مجموعة البيانات بأكملها في الذاكرة، ثم json.dump() تبني سلسلة JSON الكاملة فوق ذلك. للملفات الأكبر من 50–100 ميجابايت، انتقل إلى أسلوب البث أو اكتب NDJSON (JSON محدود بسطر جديد) — كائن JSON واحد في كل سطر.
NDJSON — كائن JSON واحد لكل سطر
import csv
import json
def csv_to_ndjson(csv_path: str, ndjson_path: str) -> int:
"""Convert CSV to NDJSON, processing one row at a time."""
count = 0
with open(csv_path, "r", encoding="utf-8") as infile, \
open(ndjson_path, "w", encoding="utf-8") as outfile:
for row in csv.DictReader(infile):
outfile.write(json.dumps(row, ensure_ascii=False) + "\n")
count += 1
return count
rows_written = csv_to_ndjson("access_log.csv", "access_log.ndjson")
print(f"Wrote {rows_written} lines to access_log.ndjson")
# Each line is a standalone JSON object:
# {"timestamp":"2026-03-15T09:12:00Z","method":"GET","path":"/api/v2/orders","status":"200"}
# {"timestamp":"2026-03-15T09:12:01Z","method":"POST","path":"/api/v2/payments","status":"201"}البث مع ijson لملفات JSON الكبيرة
import ijson # pip install ijson
def count_high_value_orders(json_path: str, threshold: float) -> int:
"""Count orders above a threshold without loading the full file."""
count = 0
with open(json_path, "rb") as f:
for item in ijson.items(f, "item"):
if float(item.get("total", 0)) > threshold:
count += 1
return count
# Process a 2 GB JSON file with constant memory usage
high_value = count_high_value_orders("all_orders.json", 500.0)
print(f"Found {high_value} orders above $500")ijson مخصصة لقراءة ملفات JSON الكبيرة — أما لجانب الكتابة، فنمط NDJSON أعلاه يُبقي استخدام الذاكرة ثابتاً بغض النظر عن حجم الملف.الأخطاء الشائعة
المشكلة: json.dumps() تُعيد سلسلة نصية. كتابتها بـ f.write() يعمل لكنه ينشئ سلسلة وسيطة غير ضرورية في الذاكرة — مكلف لمجموعات البيانات الكبيرة.
الحل: استخدم json.dump(data, f) للكتابة مباشرةً إلى كائن الملف. تبثّ الناتج دون بناء السلسلة الكاملة أولاً.
with open("output.json", "w", encoding="utf-8") as f:
json.dump(rows, f, indent=2, ensure_ascii=False) # direct writejson_string = json.dumps(rows, indent=2)
with open("output.json", "w") as f:
f.write(json_string) # unnecessary intermediate stringالمشكلة: csv.DictReader تُعيد كل القيم كسلاسل نصية. يحتوي ناتج JSON على "quantity": "5" بدلاً من "quantity": 5، مما يُعطّل مستهلكي API الذين يتحققون من الأنواع.
الحل: حوّل الأعمدة الرقمية صراحةً باستخدام int() أو float() قبل التسلسل.
rows = list(csv.DictReader(f))
for row in rows:
row["port"] = int(row["port"])
row["workers"] = int(row["workers"])
json.dumps(rows)
# [{"port": 8080, "workers": 4}] ← proper integersrows = list(csv.DictReader(f))
json.dumps(rows)
# [{"port": "8080", "workers": "4"}] ← strings, not numbersالمشكلة: على Windows، الترميز الافتراضي هو cp1252. المحارف غير ASCII (الأسماء بحروف مُعلَّمة، نصوص CJK) تتشوّه بصمت أو تُثير UnicodeDecodeError.
الحل: مرّر دائماً encoding='utf-8' إلى open() لكل من قراءة CSV وكتابة JSON.
with open("locations.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))with open("locations.csv", "r") as f: # uses system default encoding
rows = list(csv.DictReader(f))المشكلة: str(my_dict) تُنتج صياغة Python (اقتباسات مفردة، True، None) وهي ليست JSON صحيحاً. واجهات API ومحللو JSON يرفضونها.
الحل: استخدم دائماً json.dumps() لإنتاج JSON صحيح. تُحوّل True إلى true وNone إلى null وتستخدم علامات اقتباس مزدوجة.
output = json.dumps({"active": True, "note": None})
# '{"active": true, "note": null}' ← valid JSONoutput = str({"active": True, "note": None})
# "{'active': True, 'note': None}" ← NOT valid JSONjson.dumps() مقابل البدائل — مقارنة سريعة
لمعظم تحويلات CSV إلى JSON، مجموعة csv + json من المكتبة القياسية هي الخيار الأنسب: صفر تبعيات، مدمجة مع Python، تعمل في كل مكان. الجأ إلى orjson عندما يُظهر تحليل الأداء أن التسلسل هو عنق الزجاجة — الفرق في السرعة حقيقي على نطاق واسع. استخدم pandas عندما تحتاج أيضاً إلى تنظيف البيانات أو تصفيتها أو تجميعها قبل التحويل إلى JSON. إذا كنت تريد تحويلاً سريعاً دون كتابة كود، يُنجز محوّل CSV إلى JSON عبر الإنترنت المهمة فوراً.
أسئلة متكررة
ما الفرق بين json.dump() وjson.dumps() في Python؟
json.dump(obj, file) يكتب ناتج JSON مباشرةً إلى كائن شبيه بالملف (أي كائن يمتلك تابع .write()). أما json.dumps(obj) فيُعيد سلسلة نصية منسّقة بـ JSON. استخدم json.dump() عند الكتابة إلى ملف، وjson.dumps() عندما تحتاج إلى JSON كسلسلة Python للتسجيل أو التضمين في حمولة طلب أو الإرسال عبر مقبس. كلتا الدالتين تقبلان نفس المعاملات الاختيارية (indent وsort_keys وensure_ascii وdefault).
كيف أحوّل قاموس Python إلى سلسلة JSON نصية؟
استدع json.dumps(your_dict). القيمة المُعادة هي str تحتوي على JSON صحيح. أضف indent=2 للحصول على ناتج مقروء. إذا كان قاموسك يحتوي على قيم غير ASCII، مرّر ensure_ascii=False للحفاظ على المحارف كالحروف المُعلَّمة أو نصوص CJK.
import json
server_config = {"host": "api.internal", "port": 8443, "debug": False}
json_string = json.dumps(server_config, indent=2)
print(json_string)
# {
# "host": "api.internal",
# "port": 8443,
# "debug": false
# }كيف أحفظ قائمة Python من القواميس كملف JSON؟
افتح ملفاً في وضع الكتابة مع تشفير UTF-8، ثم استدع json.dump(your_list, f, indent=2, ensure_ascii=False). استخدم دائماً json.dump() (وليس json.dumps()) للكتابة في الملفات — فهو يكتب مباشرةً إلى مؤشر الملف دون إنشاء سلسلة وسيطة في الذاكرة.
import json
records = [
{"order_id": "ORD-4821", "total": 129.99, "currency": "USD"},
{"order_id": "ORD-4822", "total": 89.50, "currency": "EUR"},
]
with open("orders.json", "w", encoding="utf-8") as f:
json.dump(records, f, indent=2, ensure_ascii=False)لماذا يحوّل json.dumps() القيمة True إلى true وNone إلى null؟
القيم المنطقية في Python (True وFalse) وNone ليست رموزاً صحيحة في JSON. تستخدم مواصفة JSON الأحرف الصغيرة true وfalse وnull. يتولى json.dumps() هذا التحويل تلقائياً — True تصبح true، وFalse تصبح false، وNone تصبح null. لا تحتاج إلى تحويل هذه القيم يدوياً. في الاتجاه العكسي، يُعيدها json.loads() إلى أنواع Python.
كيف أتعامل مع كائنات datetime عند تحويل بيانات CSV إلى JSON؟
مرّر دالة default= إلى json.dumps() تُحوّل كائنات datetime إلى سلاسل ISO 8601 النصية. تُستدعى دالة default هذه لأي كائن لا تستطيع json تسلسله بطبيعتها. أعد obj.isoformat() لنسخ datetime وأثِر TypeError لأي شيء آخر.
import json
from datetime import datetime
def json_default(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not serializable: {type(obj)}")
event = {"action": "login", "timestamp": datetime(2026, 3, 15, 9, 30, 0)}
print(json.dumps(event, default=json_default))
# {"action": "login", "timestamp": "2026-03-15T09:30:00"}هل يمكنني تحويل CSV إلى JSON بدون pandas؟
نعم. تحتوي المكتبة القياسية لـ Python على كل ما تحتاجه. استخدم csv.DictReader لقراءة كل صف كقاموس، واجمع الصفوف في قائمة، وتسلسلها باستخدام json.dump() أو json.dumps(). لا تحتاج إلى مكتبات خارجية. pandas يستحق الإضافة فقط إذا كنت بحاجة إلى تنظيف البيانات أو استنتاج الأنواع أو كنت تستخدمه مسبقاً في المشروع.
import csv
import json
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
rows = list(csv.DictReader(csv_file))
with open("inventory.json", "w", encoding="utf-8") as json_file:
json.dump(rows, json_file, indent=2, ensure_ascii=False)للحصول على بديل بنقرة واحدة دون كتابة أي Python، جرّب محوّل CSV إلى JSON — الصق بيانات CSV وستحصل على ناتج JSON منسّق فوراً.
أدوات ذات صلة
Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.
Priya is a data scientist and machine learning engineer who has worked across the full Python data stack — from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.