إدخال/إخراج الملفات

حتى الآن، بيانات برنامجنا كانت موجودة فقط في الذاكرة — أغلق البرنامج، وتفقد البيانات. إدخال/إخراج الملفات يسمح للبرامج بحفظ البيانات على القرص وقراءتها مرة أخرى عند التشغيل التالي. هذه قدرة أساسية لأي تطبيق عملي.


1. فتح وإغلاق الملفات

عملية الملف الأساسية لها ثلاث خطوات: فتح ← قراءة/كتابة ← إغلاق.

مثال: فتح وإغلاق ملف يدوياً

PYTHON
# اكتب إلى ملف
file = open("hello.txt", "w", encoding="utf-8")
file.write("Hello, World!")
file.close()

# اقرأ من ملف
file = open("hello.txt", "r", encoding="utf-8")
content = file.read()
file.close()

print(content)              # Hello, World!
▶ جرّب الكود
⚠️ تذكر دائماً close()! الملفات المفتوحة تستهلك موارد النظام. نسيان الإغلاق يمكن أن يؤدي إلى تلف الملف أو استنفاد الموارد. لكن لا تقلق — القسم التالي لديه نهج أفضل.


2. جملة with (مدير السياق)

جملة with تُغلق الملف تلقائياً في نهاية كتلة الكود، دون الحاجة لاستدعاء close():

مثال: إدخال/إخراج ملف آمن باستخدام with

PYTHON
# كتابة
with open("hello.txt", "w", encoding="utf-8") as f:
    f.write("Hello, World!")

# قراءة
with open("hello.txt", "r", encoding="utf-8") as f:
    content = f.read()

print(content)
▶ جرّب الكود
💡 استخدم دائماً with لعمليات الملفات. إنها الطريقة الأكثر أماناً وبايثونية — الملف يُغلق بشكل صحيح سواء حدث استثناء في كتلة الكود أم لا.


3. أوضاع فتح الملف

المعامل الثاني لـ open() هو الوضع:

الوضع المعنى الملف موجود الملف غير موجود
"r" قراءة (افتراضي) قراءة عادية خطأ
"w" كتابة مسح ثم كتابة إنشاء
"a" إلحاق إلحاق بالنهاية إنشاء
"x" إنشاء حصري خطأ إنشاء
"r+" قراءة وكتابة قابل للقراءة والكتابة خطأ

مثال: أوضاع فتح ملف مختلفة

PYTHON
# "w" — كتابة (مسح وإعادة كتابة)
with open("test.txt", "w", encoding="utf-8") as f:
    f.write("First line\n")
    f.write("Second line\n")

# "a" — إلحاق
with open("test.txt", "a", encoding="utf-8") as f:
    f.write("Third line\n")

# "r" — قراءة
with open("test.txt", "r", encoding="utf-8") as f:
    print(f.read())
▶ جرّب الكود

المخرجات:

TEXT
First line
Second line
Third line

4. طرق قراءة الملفات

مثال: ثلاث طرق لقراءة ملف

PYTHON
# الطريقة 1: read() — قراءة الكل مرة واحدة
with open("test.txt", "r", encoding="utf-8") as f:
    content = f.read()
print(content)

# الطريقة 2: readlines() — قراءة كقائمة
with open("test.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()
print(lines)

# الطريقة 3: سطراً بسطر (موصى به)
with open("test.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())
▶ جرّب الكود

مثال: أداة نسخ احتياطي للملف (الصعوبة ⭐⭐)

PYTHON
def backup_file(filename):
    """أنشئ نسخة احتياطية من ملف"""
    try:
        with open(filename, "r", encoding="utf-8") as f:
            content = f.read()
        
        backup_name = filename + ".bak"
        with open(backup_name, "w", encoding="utf-8") as f:
            f.write(content)
        
        print(f"Backup created: {backup_name}")
    except FileNotFoundError:
        print(f"File {filename} does not exist!")

backup_file("test.txt")
▶ جرّب الكود

5. قراءة وكتابة ملفات CSV

CSV (Comma-Separated Values) هو تنسيق تبادل البيانات الأكثر شيوعاً. يحتوي بايثون على وحدة csv مدمجة:

مثال: إدخال/إخراج ملف CSV

PYTHON
import csv

# كتابة CSV
data = [
    ["Name", "Age", "City"],
    ["Zhang San", 25, "Beijing"],
    ["Li Si", 30, "Shanghai"],
    ["Wang Wu", 22, "Guangzhou"],
]

with open("students.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerows(data)

# قراءة CSV
with open("students.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)
▶ جرّب الكود

المخرجات:

TEXT
['Name', 'Age', 'City']
['Zhang San', '25', 'Beijing']
['Li Si', '30', 'Shanghai']
['Wang Wu', '22', 'Guangzhou']

6. معالجة المسارات

استخدم os.path أو pathlib لمعالجة مسارات الملفات — أكثر أماناً من دمج السلاسل النصية:

مثال: os.path لمعالجة المسارات

PYTHON
import os

# احصل على الدليل الحالي
print(os.getcwd())          # /project

# ادمج المسارات (تتعامل مع الفواصل تلقائياً)
path = os.path.join("data", "files", "test.txt")
print(path)                 # data/files/test.txt

# تحقق مما إذا كان المسار موجوداً
print(os.path.exists("test.txt"))          # True/False
print(os.path.isfile("test.txt"))          # هل هو ملف؟
print(os.path.isdir("data"))               # هل هو دليل؟

# احصل على معلومات الملف
print(os.path.getsize("test.txt"))         # حجم الملف بالبايتات

# اعرض محتويات الدليل
for f in os.listdir("."):
    print(f)
▶ جرّب الكود

موصى به: pathlib (بايثون 3.4+)

مثال: عمليات المسار باستخدام pathlib

PYTHON
from pathlib import Path

# أنشئ مساراً
p = Path("data/files/test.txt")

# معلومات المسار
print(p.name)               # test.txt (اسم الملف)
print(p.stem)               # test (بدون امتداد)
print(p.suffix)             # .txt (الامتداد)
print(p.parent)             # data/files (الدليل الأصلي)

# قراءة/كتابة الملف (موجز)
p = Path("hello.txt")
p.write_text("Hello, World!", encoding="utf-8")
content = p.read_text(encoding="utf-8")
print(content)              # Hello, World!

# اجتياز تكراري
for py_file in Path(".").rglob("*.py"):
    print(py_file)
▶ جرّب الكود
💡 pathlib هي الطريقة الموصى بها للتعامل مع المسارات في بايثون 3.4+. إنها أكثر كائنية التوجه وبديهية من os.path. للمشاريع الجديدة، استخدم pathlib.


حالات الاستخدام الشائعة


❓ أسئلة شائعة

س هل أحتاج دائماً لكتابة encoding="utf-8"؟
ج في البيئات العربية/الصينية، يُوصى بشدة في كل مرة. الترميز الافتراضي لبايثون يختلف حسب نظام التشغيل — ويندوز يستخدم gbk، macOS/لينكس يستخدم utf-8. بدون تحديد، معالجة ملفات نصية عربية/صينية على ويندوز قد تنتج نتائج مشوشة. اجعلها عادة لتحديد الترميز لراحة البال عبر المنصات. س:الوضع "w" يمسح محتوى الملف الموجود. كيف أتجنب الاستبدال العرضي؟ ج:استخدم الوضع "x" (إنشاء حصري) — إذا كان الملف موجوداً بالفعل، يثير خطأ بدلاً من مسحه. أو استخدم os.path.exists() للتحقق أولاً. البيانات ثمينة — فكر مرتين قبل الكتابة إلى ملف. س:كيف أقرأ ملفات كبيرة جداً (مئات الميغابايت)؟ ج:لا تستخدم read() أو readlines() — إنها تحمّل الملف بأكمله في الذاكرة. استخدم for line in file: للقراءة سطراً بسطر، معالجة سطر واحد فقط في كل مرة بأقل استخدام للذاكرة. بدلاً من ذلك، استخدم read(1024) لقراءة عدد محدد من البايتات في كل مرة.

📖 ملخص

  • عمليات الملفات بثلاث خطوات: open() ← قراءة/كتابة ← close()
  • جملة with تدير إغلاق الملف تلقائياً — النهج الأكثر أماناً
  • الأوضاع: "r" قراءة، "w" كتابة، "a" إلحاق
  • طرق القراءة: read() محتوى كامل، readlines() كقائمة، for line in f سطراً بسطر
  • وحدة csv لإدخال/إخراج ملفات CSV؛ تدعم DictReader/DictWriter
  • os.path و pathlib لمعالجة مسارات الملفات؛ pathlib أكثر حداثة
  • حدد دائماً encoding="utf-8" لعمليات الملفات النصية

📝 تمارين

  1. أساسي (الصعوبة ⭐): اكتب برنامجاً يقبل اسم المستخدم وعمره ويحفظهما في ملف users.txt (مستخدم واحد لكل سطر، التنسيق: name,age). ألحق سجلات جديدة في كل تشغيل دون الكتابة فوق البيانات الموجودة.

  2. متوسط (الصعوبة ⭐⭐): اكتب برنامجاً يقرأ ملف users.txt من التمرين السابق، يحلل كل سطر، ويحسب ويخرج متوسط أعمار المستخدمين. تلميح: استخدم split(",") للتحليل، int() لتحويل العمر.

  3. تحدي (الصعوبة ⭐⭐⭐): اكتب برنامج "مفكرة بسيطة." الميزات: add:title|content لإضافة ملاحظة (ألحق بـ notes.csvlist لعرض جميع الملاحظات، search:keyword للبحث في الملاحظات. خزّن بتنسيق CSV (الحقول: العنوان، المحتوى، وقت الإنشاء). تلميح: استخدم datetime.now() للطابع الزمني الحالي.

100%