لقراءة وكتابة ملفات CSV في بايثون لا تحتاج إلى تثبيت مكتبة خارجية؛ فالوحدة المدمجة csv توفر csv.reader() لقراءة الصفوف كقوائم، وcsv.writer() لكتابتها. وإذا كان الملف يحتوي على أسماء أعمدة، يمكنك استخدام csv.DictReader() لقراءة كل صف كقاموس، وcsv.DictWriter() لكتابة القواميس مباشرة.
سنطبّق هذه الأدوات خطوة بخطوة، مع توضيح newline="" وencoding="utf-8"، والتعامل مع صف العناوين وتحويل القيم الرقمية من نصوص إلى أرقام. هذا هو الدرس 30 من كورس أساسيات بايثون.
القاعدة العملية سهلة: استخدم reader وwriter للبيانات البسيطة المبنية على القوائم، وانتقل إلى DictReader وDictWriter عندما يكون لديك Header وتريد التعامل مع الأعمدة بأسمائها بدل أرقام الفهارس.
الفكرة ببساطة: استخدم reader وwriter عندما تتعامل مع الصفوف كقوائم، واستخدم DictReader وDictWriter عندما تريد الوصول إلى القيم بأسماء الأعمدة.
ما هو ملف CSV؟
كلمة CSV اختصار لعبارة Comma-Separated Values، ومعناها: قيم مفصولة بفواصل. وهو نوع من الملفات النصية يستخدم لتخزين البيانات في شكل قريب من الجداول.
مثال بسيط على ملف CSV:
name,age,city
Ali,25,Aden
Sara,22,Sanaa
Omar,30,Taiz
في هذا المثال:
- السطر الأول يحتوي على أسماء الأعمدة:
nameوageوcity. - كل سطر بعد ذلك يمثل صفًا من البيانات.
- كل قيمة مفصولة عن القيمة التالية بفاصلة.
إذا فتحت هذا الملف في Excel أو Google Sheets، فغالبًا سيظهر لك كجدول منظم.
لماذا نستخدم ملفات CSV؟
ملفات CSV منتشرة جدًا لأنها بسيطة وخفيفة ويمكن فتحها في برامج كثيرة. ستجدها في التقارير، قواعد البيانات، ملفات التصدير من الأنظمة، وبيانات التحليل.
نستخدم ملفات CSV في حالات مثل:
- حفظ بيانات الطلاب أو المستخدمين.
- تخزين تقارير المبيعات والمصاريف.
- تصدير بيانات من برنامج أو موقع.
- قراءة بيانات جداول داخل بايثون.
- تجهيز بيانات بسيطة لمشاريع تحليل البيانات.
- تبادل البيانات بين بايثون و Excel.
لذلك فهم ملفات CSV خطوة مهمة جدًا قبل الدخول إلى موضوعات مثل تحليل البيانات و pandas لاحقًا.
ما الفرق بين CSV و JSON؟
في الدرس السابق تعلمنا قراءة وكتابة JSON في بايثون. وقد تتساءل: متى أستخدم CSV ومتى أستخدم JSON؟
| المقارنة | CSV | JSON |
|---|---|---|
| الشكل | صفوف وأعمدة | بيانات منظمة على شكل مفاتيح وقيم |
| مناسب لـ | الجداول والتقارير | البيانات المتداخلة والإعدادات |
| سهولة القراءة في Excel | ممتازة | أقل مباشرة |
| التداخل | ضعيف | يدعم قوائم وقواميس متداخلة |
| مثال استخدام | قائمة طلاب ودرجاتهم | إعدادات تطبيق أو بيانات مستخدم مفصلة |
إذا كانت بياناتك تشبه جدولًا بسيطًا، فغالبًا CSV خيار مناسب. أما إذا كانت البيانات متداخلة ومعقدة، فقد يكون JSON أفضل.
استيراد مكتبة csv في بايثون
بايثون يأتي مع مكتبة مدمجة اسمها csv، لذلك لا تحتاج إلى تثبيتها باستخدام pip. يكفي أن تستوردها في بداية الملف:
import csv
بعد ذلك يمكنك استخدام أدوات المكتبة مثل:
csv.reader()لقراءة ملفات CSV.csv.writer()لكتابة ملفات CSV.csv.DictReader()لقراءة CSV كقواميس.csv.DictWriter()لكتابة CSV باستخدام القواميس.
| الأداة | ما الذي تفعله؟ | شكل البيانات |
|---|---|---|
csv.reader() |
قراءة الصفوف | كل صف list |
csv.writer() |
كتابة الصفوف | قوائم أو tuples |
csv.DictReader() |
قراءة الصفوف بأسماء الأعمدة | كل صف dict |
csv.DictWriter() |
كتابة البيانات بأسماء الأعمدة | قواميس مع fieldnames |
إنشاء ملف CSV للتجربة
قبل القراءة من بايثون، أنشئ ملفًا جديدًا باسم students.csv وضع فيه البيانات التالية:
name,age,grade
Ali,20,90
Sara,22,85
Omar,19,78
احفظ الملف في نفس مجلد ملف بايثون الذي ستكتب فيه الكود. هذا مهم حتى يستطيع بايثون العثور على الملف بسهولة.
تنبيه مهم: إذا ظهر FileNotFoundError عند قراءة ملف CSV، فتحقق من اسم الملف والمسار والمجلد الذي يعمل منه البرنامج. راجع حل خطأ FileNotFoundError في بايثون إذا استمرت المشكلة.
قراءة ملف CSV باستخدام csv.reader
أبسط طريقة لقراءة ملف CSV هي استخدام csv.reader(). هذا الأسلوب يقرأ كل صف كقائمة list.
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
for row in reader:
print(row)
الناتج سيكون تقريبًا:
['name', 'age', 'grade']
['Ali', '20', '90']
['Sara', '22', '85']
['Omar', '19', '78']
لاحظ أن كل صف أصبح قائمة. حتى الأرقام مثل 20 و 90 ظهرت كنصوص؛ لأن CSV ملف نصي في الأصل.
تجاهل أول صف في CSV
غالبًا يكون أول صف في ملف CSV هو أسماء الأعمدة، مثل name,age,grade. إذا أردت تجاهله وقراءة البيانات فقط، يمكنك استخدام next().
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
headers = next(reader)
for row in reader:
print(row)
الناتج:
['Ali', '20', '90']
['Sara', '22', '85']
['Omar', '19', '78']
المتغير headers سيحتوي على أسماء الأعمدة إذا احتجت إليها لاحقًا.
الوصول إلى قيم محددة داخل الصف
بما أن كل صف يقرأه csv.reader يكون قائمة، يمكنك الوصول إلى العناصر باستخدام الفهرس.
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
next(reader)
for row in reader:
name = row[0]
age = row[1]
grade = row[2]
print(name, age, grade)
الناتج:
Ali 20 90
Sara 22 85
Omar 19 78
هذه الطريقة جيدة كبداية، لكنها تصبح أقل وضوحًا عندما تكون الأعمدة كثيرة. لذلك سنرى بعد قليل طريقة DictReader.
تحويل القيم الرقمية من نص إلى رقم
ملفات CSV تخزن كل شيء كنص. إذا أردت التعامل مع الدرجة كرقم، يجب تحويلها باستخدام int().
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.reader(file)
next(reader)
for row in reader:
name = row[0]
grade = int(row[2])
if grade >= 85:
print(name, "ناجح بتقدير مرتفع")
هنا حولنا الدرجة من نص إلى رقم حتى نستطيع المقارنة باستخدام >=.
قراءة CSV باستخدام DictReader
طريقة csv.DictReader() تجعل قراءة CSV أوضح؛ لأنها تتعامل مع كل صف كقاموس dict، وتستخدم أسماء الأعمدة كمفاتيح.
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file)
for row in reader:
print(row["name"], row["grade"])
الناتج:
Ali 90
Sara 85
Omar 78
هذه الطريقة أوضح من استخدام row[0] و row[1]، لأنك تكتب اسم العمود مباشرة.
نصيحة عملية: إذا كان ملف CSV يحتوي على أسماء أعمدة واضحة، فغالبًا DictReader سيكون أسهل وأوضح من reader.
ماذا لو لم يحتوي ملف CSV على صف عناوين؟
يمكنك إعطاء DictReader أسماء الأعمدة بنفسك عبر fieldnames. في هذه الحالة سيُعامل أول صف في الملف كبيانات، لأن أسماء الأعمدة جاءت من الكود:
import csv
columns = ["name", "age", "grade"]
with open("students_no_header.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file, fieldnames=columns)
for row in reader:
print(row["name"], row["grade"])
كتابة ملف CSV باستخدام csv.writer
كما يمكننا قراءة ملفات CSV، يمكننا أيضًا إنشاء ملف CSV جديد وكتابة بيانات داخله باستخدام csv.writer().
import csv
with open("new_students.csv", "w", encoding="utf-8", newline="") as file:
writer = csv.writer(file)
writer.writerow(["name", "age", "grade"])
writer.writerow(["Ali", 20, 90])
writer.writerow(["Sara", 22, 85])
writer.writerow(["Omar", 19, 78])
بعد تشغيل الكود سيتم إنشاء ملف جديد باسم new_students.csv.
محتوى الملف سيكون:
name,age,grade
Ali,20,90
Sara,22,85
Omar,19,78
لماذا نستخدم newline="" مع ملفات CSV؟
قد تلاحظ أننا كتبنا:
newline=""
توصي مكتبة csv بفتح ملف CSV مع newline="" حتى تتعامل الوحدة نفسها مع نهايات الأسطر دون تدخل إضافي من طبقة النص. ويظهر أثر ذلك بوضوح عند الكتابة، إذ يساعد على منع الأسطر الفارغة الإضافية في بعض البيئات.
لذلك استخدمه مع ملفات CSV عند القراءة أو الكتابة، ومثال الكتابة:
open("file.csv", "w", encoding="utf-8", newline="")
كتابة عدة صفوف باستخدام writerows
إذا كانت لديك البيانات داخل قائمة كبيرة، يمكنك استخدام writerows() بدل كتابة writerow() عدة مرات.
import csv
students = [
["name", "age", "grade"],
["Ali", 20, 90],
["Sara", 22, 85],
["Omar", 19, 78]
]
with open("students_output.csv", "w", encoding="utf-8", newline="") as file:
writer = csv.writer(file)
writer.writerows(students)
هذه الطريقة مناسبة عندما تكون البيانات جاهزة داخل قائمة.
كتابة CSV باستخدام DictWriter
إذا كانت بياناتك على شكل قواميس، فيمكنك استخدام csv.DictWriter().
import csv
students = [
{"name": "Ali", "age": 20, "grade": 90},
{"name": "Sara", "age": 22, "grade": 85},
{"name": "Omar", "age": 19, "grade": 78}
]
with open("students_dict.csv", "w", encoding="utf-8", newline="") as file:
fieldnames = ["name", "age", "grade"]
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(students)
هذه الطريقة مفيدة لأن أسماء الأعمدة تكون واضحة، والبيانات منظمة في قواميس.
إضافة صف جديد إلى ملف CSV
إذا أردت إضافة بيانات إلى ملف موجود دون حذف المحتوى القديم، استخدم وضع الإضافة "a" بدل وضع الكتابة "w".
import csv
with open("students.csv", "a", encoding="utf-8", newline="") as file:
writer = csv.writer(file)
writer.writerow(["Mona", 21, 88])
بهذا الشكل ستتم إضافة صف جديد في نهاية الملف.
تحذير: وضع "w" يمسح محتوى الملف القديم ويكتب من جديد، أما وضع "a" فيضيف في نهاية الملف.
استخدام pathlib مع CSV
في المشاريع المنظمة، من الأفضل وضع ملفات البيانات داخل مجلد مثل data واستخدام pathlib لبناء المسارات.
import csv
from pathlib import Path
file_path = Path("data") / "students.csv"
with file_path.open("r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file)
for row in reader:
print(row["name"])
هذا الأسلوب مناسب عندما تضع البيانات داخل مجلد مستقل في المشروع. ولتطبيق الفكرة ضمن بنية مشروع أكبر، راجع قراءة ملفات CSV داخل مشروع بايثون بعد الأساسيات.
التعامل مع ملفات CSV تحتوي على العربية
إذا كان ملف CSV يحتوي على نص عربي، فمن الأفضل استخدام:
encoding="utf-8"
مثال:
import csv
students = [
["الاسم", "العمر", "المدينة"],
["علي", 25, "عدن"],
["سارة", 22, "صنعاء"]
]
with open("arabic_students.csv", "w", encoding="utf-8", newline="") as file:
writer = csv.writer(file)
writer.writerows(students)
إذا فتحت الملف في بعض البرامج وظهرت العربية بشكل غير صحيح، فقد تحتاج إلى التأكد من أن البرنامج نفسه يقرأ الملف بترميز UTF-8.
ماذا لو كان الفاصل ليس فاصلة؟
رغم أن اسم CSV يعني قيم مفصولة بفواصل، إلا أن بعض الملفات تستخدم فاصلة منقوطة ; أو علامة تبويب بدل الفاصلة.
مثال ملف يستخدم فاصلة منقوطة:
name;age;city
Ali;25;Aden
Sara;22;Sanaa
لقراءته في بايثون، حدد الفاصل باستخدام delimiter:
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.reader(file, delimiter=";")
for row in reader:
print(row)
إذا قرأت ملف CSV وظهر كل الصف كقيمة واحدة، فقد يكون السبب أن الفاصل المستخدم ليس فاصلة عادية.
أخطاء شائعة عند التعامل مع CSV في بايثون
1. نسيان أن القيم تقرأ كنصوص
عند قراءة CSV، الأرقام تقرأ كنصوص. لذلك إذا أردت إجراء عمليات حسابية أو مقارنات رقمية، حوّلها باستخدام int() أو float().
2. نسيان newline="" عند فتح ملف CSV
استخدم newline="" عند فتح ملفات CSV للقراءة أو الكتابة حتى تتولى مكتبة csv معالجة نهايات الأسطر بشكل صحيح؛ وهو مهم خصوصًا عند الكتابة على Windows.
3. مشكلة الترميز مع العربية
إذا ظهرت الحروف العربية بشكل غير مفهوم، استخدم encoding="utf-8" عند فتح الملف.
4. استخدام الفاصل الخطأ
إذا كان الملف يستخدم ; بدل ,، يجب تحديد ذلك باستخدام delimiter=";".
5. فتح الملف بوضع w بدل a
استخدام "w" يمسح الملف القديم. إذا أردت إضافة صفوف جديدة، استخدم "a".
6. عدم وجود الملف في المسار الصحيح
إذا ظهر FileNotFoundError، راجع مكان الملف واسمه وامتداده.
مثال عملي كامل: قراءة درجات الطلاب وحساب المتوسط
لنفترض أن لدينا ملف students.csv بهذا الشكل:
name,grade
Ali,90
Sara,85
Omar,78
نريد قراءة الدرجات وحساب المتوسط:
import csv
total = 0
count = 0
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file)
for row in reader:
grade = int(row["grade"])
total = total + grade
count = count + 1
average = total / count
print("متوسط الدرجات:", average)
الناتج:
متوسط الدرجات: 84.33333333333333
هذا مثال بسيط لكنه مهم جدًا؛ لأنه يوضح كيف نستخدم CSV في مشروع عملي صغير.
مثال عملي: فلترة الطلاب الناجحين
يمكننا أيضًا قراءة ملف CSV وطباعة الطلاب الذين حصلوا على درجة أكبر من أو تساوي 80.
import csv
with open("students.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file)
for row in reader:
grade = int(row["grade"])
if grade >= 80:
print(row["name"], "ناجح")
هذا المثال يربط بين ملفات CSV وما تعلمته سابقًا عن الشروط والحلقات والقوائم.
تدريب عملي
أنشئ ملفًا باسم products.csv يحتوي على البيانات التالية:
name,price,quantity
Pen,2,10
Book,5,3
Bag,20,1
ثم اكتب برنامج بايثون يقوم بالآتي:
- يقرأ الملف باستخدام
csv.DictReader. - يحول السعر والكمية إلى أرقام.
- يحسب إجمالي كل منتج: السعر × الكمية.
- يطبع اسم المنتج والإجمالي.
حل مختصر للتدريب
import csv
with open("products.csv", "r", encoding="utf-8", newline="") as file:
reader = csv.DictReader(file)
for row in reader:
price = float(row["price"])
quantity = int(row["quantity"])
total = price * quantity
print(row["name"], "-", total)
الناتج:
Pen - 20.0
Book - 15.0
Bag - 20.0
أفضل ممارسات التعامل مع CSV
- استخدم
encoding="utf-8"عند وجود نصوص عربية. - استخدم
newline=""عند فتح ملفات CSV للقراءة أو الكتابة. - استخدم
DictReaderعندما يحتوي الملف على أسماء أعمدة. - حوّل الأرقام من نصوص إلى
intأوfloatعند الحاجة. - ضع ملفات CSV داخل مجلد
dataفي المشاريع المنظمة. - لا تستخدم وضع
"w"إذا كنت تريد الحفاظ على البيانات القديمة. - تأكد من نوع الفاصل المستخدم في الملف: فاصلة أو فاصلة منقوطة.
ماذا بعد تعلم ملفات CSV؟
إذا أصبحت مرتاحًا مع reader وwriter وDictReader وDictWriter، فالخطوة التالية هي تطبيق CSV داخل مشروع منظم ثم الانتقال إلى أدوات تحليل البيانات عند الحاجة. ولا تنسَ أن أساس التعامل مع CSV يعتمد أيضًا على فهم فتح وقراءة وكتابة الملفات في بايثون.
مصادر خارجية مفيدة للتوسع
الخلاصة
ملفات CSV من أكثر أنواع الملفات استخدامًا لتخزين البيانات الجدولية، مثل الطلاب والمنتجات والتقارير. في بايثون يمكنك قراءة وكتابة CSV بسهولة باستخدام مكتبة csv المدمجة.
تعلمنا في هذا الدرس استخدام csv.reader و csv.writer، ثم تعرفنا على DictReader و DictWriter لجعل التعامل مع الأعمدة أوضح. كما تعلمنا أهمية encoding="utf-8" مع العربية، و newline="" عند الكتابة، وتحويل الأرقام من نصوص إلى أرقام عند الحاجة.
الخلاصة العملية: إذا كانت بياناتك على شكل جدول بسيط، فملف CSV خيار ممتاز، ومكتبة csv في بايثون تمنحك طريقة سهلة لقراءته وكتابته بدون تثبيت أي مكتبات إضافية.
أسئلة شائعة مع إجاباتها
ما هو ملف CSV؟
هو ملف نصي يخزن البيانات على شكل صفوف وأعمدة، وغالبًا تكون القيم مفصولة بفواصل.
هل أحتاج إلى تثبيت مكتبة csv؟
لا. مكتبة csv مدمجة مع بايثون، ويكفي أن تكتب import csv.
ما الفرق بين csv.reader و csv.DictReader؟
csv.reader يقرأ كل صف كقائمة، أما csv.DictReader فيقرأ كل صف كقاموس باستخدام أسماء الأعمدة كمفاتيح.
لماذا تظهر الأرقام كنصوص عند قراءة CSV؟
لأن ملف CSV ملف نصي في الأصل، لذلك تحتاج إلى تحويل الأرقام باستخدام int() أو float() عند الحاجة.
لماذا نستخدم newline="" مع ملفات CSV؟
نستخدمه حتى تتعامل مكتبة csv مع نهايات الأسطر بشكل صحيح، وهو يساعد خصوصًا عند الكتابة على منع ظهور أسطر فارغة إضافية في بعض البيئات.
كيف أتعامل مع CSV يحتوي على نص عربي؟
استخدم encoding="utf-8" عند فتح الملف للقراءة أو الكتابة، وتأكد أن البرنامج الذي يفتح الملف يدعم UTF-8.



