مقالات مختارة

قراءة وكتابة ملفات CSV في بايثون | أساسيات بايثون 30

شرح ملفات CSV في بايثون للمبتدئين ضمن كورس أساسيات بايثون

لقراءة وكتابة ملفات 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 منتشرة جدًا لأنها بسيطة وخفيفة ويمكن فتحها في برامج كثيرة. ستجدها في التقارير، قواعد البيانات، ملفات التصدير من الأنظمة، وبيانات التحليل.

نستخدم ملفات 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 و reader للمبتدئين

تجاهل أول صف في 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
كتابة ملف CSV في بايثون باستخدام csv writer وإضافة صفوف بيانات

لماذا نستخدم 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 في بايثون

أخطاء شائعة عند التعامل مع ملفات 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

ثم اكتب برنامج بايثون يقوم بالآتي:

  1. يقرأ الملف باستخدام csv.DictReader.
  2. يحول السعر والكمية إلى أرقام.
  3. يحسب إجمالي كل منتج: السعر × الكمية.
  4. يطبع اسم المنتج والإجمالي.

حل مختصر للتدريب

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.

Admin
Admin
تعليقات