إدخال/إخراج الملفات
حتى الآن، بيانات برنامجنا كانت موجودة فقط في الذاكرة — أغلق البرنامج، وتفقد البيانات. إدخال/إخراج الملفات يسمح للبرامج بحفظ البيانات على القرص وقراءتها مرة أخرى عند التشغيل التالي. هذه قدرة أساسية لأي تطبيق عملي.
1. فتح وإغلاق الملفات
عملية الملف الأساسية لها ثلاث خطوات: فتح ← قراءة/كتابة ← إغلاق.
مثال: فتح وإغلاق ملف يدوياً
# اكتب إلى ملف
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
# كتابة
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+" |
قراءة وكتابة | قابل للقراءة والكتابة | خطأ |
مثال: أوضاع فتح ملف مختلفة
# "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())
المخرجات:
First line
Second line
Third line
4. طرق قراءة الملفات
مثال: ثلاث طرق لقراءة ملف
# الطريقة 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())
مثال: أداة نسخ احتياطي للملف (الصعوبة ⭐⭐)
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
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)
المخرجات:
['Name', 'Age', 'City']
['Zhang San', '25', 'Beijing']
['Li Si', '30', 'Shanghai']
['Wang Wu', '22', 'Guangzhou']
6. معالجة المسارات
استخدم os.path أو pathlib لمعالجة مسارات الملفات — أكثر أماناً من دمج السلاسل النصية:
مثال: os.path لمعالجة المسارات
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
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.
حالات الاستخدام الشائعة
- استمرار البيانات: حفظ بيانات البرنامج في ملفات، واستعادتها عند التشغيل التالي.
- التسجيل: إلحاق معلومات تشغيل البرنامج بملفات السجل.
- إدارة التهيئة: قراءة ملفات التهيئة (
.ini,.json,.env). - استيراد/تصدير البيانات: تبادل البيانات مع Excel/قواعد البيانات باستخدام تنسيق CSV.
- معالجة الملفات دفعة واحدة: اجتياز الدلائل، تعديل محتوى الملفات أو إعادة تسميتها بشكل جماعي.
❓ أسئلة شائعة
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"لعمليات الملفات النصية
📝 تمارين
-
أساسي (الصعوبة ⭐): اكتب برنامجاً يقبل اسم المستخدم وعمره ويحفظهما في ملف
users.txt(مستخدم واحد لكل سطر، التنسيق:name,age). ألحق سجلات جديدة في كل تشغيل دون الكتابة فوق البيانات الموجودة. -
متوسط (الصعوبة ⭐⭐): اكتب برنامجاً يقرأ ملف
users.txtمن التمرين السابق، يحلل كل سطر، ويحسب ويخرج متوسط أعمار المستخدمين. تلميح: استخدمsplit(",")للتحليل،int()لتحويل العمر. -
تحدي (الصعوبة ⭐⭐⭐): اكتب برنامج "مفكرة بسيطة." الميزات:
add:title|contentلإضافة ملاحظة (ألحق بـnotes.csv)،listلعرض جميع الملاحظات،search:keywordللبحث في الملاحظات. خزّن بتنسيق CSV (الحقول: العنوان، المحتوى، وقت الإنشاء). تلميح: استخدمdatetime.now()للطابع الزمني الحالي.



