0%
التعامل مع الملفات في Python

الملفات

أدِر عمليات الإدخال والإخراج في برامجك بكفاءة

10-15 دقيقة

التعامل مع الملفات في Python

يُعدّ التعامل مع الملفات مهارة أساسية في البرمجة، فهو ضروري لحفظ البيانات ومعالجة المعلومات وأتمتة المهام. توفّر Python أدوات قوية ومرنة للعمل مع أنواع مختلفة من الملفات. سنستعرض في هذا الدرس كيفية قراءة الملفات وكتابتها ومعالجتها في Python.

أساسيات التعامل مع الملفات

فتح الملفات وإغلاقها

في Python، تستخدم الدالة open() لفتح ملف، وهي تُرجع كائن ملف:

# Ouvrir un fichier en mode lecture
fichier = open("mon_fichier.txt", "r")

# Opérations sur le fichier
# ...

# Fermer le fichier
fichier.close()

تأخذ الدالة open() معاملين رئيسيين:

  • مسار الملف (يمكن أن يكون مطلقًا أو نسبيًا)
  • وضع الفتح (قراءة، كتابة، إلخ)

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

توفّر Python عدة أوضاع لفتح الملفات:

  • 'r' : القراءة (الوضع الافتراضي)
  • 'w' : الكتابة (تنشئ ملفًا جديدًا أو تستبدل ملفًا موجودًا)
  • 'a' : الإلحاق (تضيف المحتوى في نهاية ملف موجود)
  • 'b' : الوضع الثنائي (مثلًا 'rb' للقراءة بشكل ثنائي)
  • 't' : الوضع النصي (افتراضي، مثلًا 'rt' لقراءة النص)
  • '+' : وضع التحديث (القراءة والكتابة، مثلًا 'r+')

استخدام الكتلة with

أفضل ممارسة للعمل مع الملفات هي استخدام الكتلة with، التي تتولى إغلاق الملف تلقائيًا حتى في حال حدوث خطأ:

# Meilleure façon d'ouvrir un fichier
with open("mon_fichier.txt", "r") as fichier:
    # Opérations sur le fichier
    contenu = fichier.read()
    print(contenu)
# Le fichier est automatiquement fermé à la sortie du bloc with

قراءة الملفات

توفّر Python عدة طرق لقراءة محتوى الملف.

قراءة الملف بالكامل

with open("mon_fichier.txt", "r") as fichier:
    contenu = fichier.read()
    print(contenu)

القراءة سطرًا بسطر

with open("mon_fichier.txt", "r") as fichier:
    # Lire la première ligne
    premiere_ligne = fichier.readline()
    print(premiere_ligne)
    
    # Lire la deuxième ligne
    deuxieme_ligne = fichier.readline()
    print(deuxieme_ligne)

قراءة جميع الأسطر في قائمة

with open("mon_fichier.txt", "r") as fichier:
    lignes = fichier.readlines()
    for ligne in lignes:
        print(ligne.strip())  # strip() supprime les espaces et les sauts de ligne

المرور على الملف سطرًا بسطر (طريقة فعّالة للملفات الكبيرة)

with open("mon_fichier.txt", "r") as fichier:
    for ligne in fichier:
        print(ligne.strip())

هذه الطريقة الأخيرة فعّالة بشكل خاص للملفات الضخمة لأنها لا تحمّل في الذاكرة سوى سطر واحد في كل مرة.

الكتابة في الملفات

كتابة نص

with open("mon_fichier.txt", "w") as fichier:
    fichier.write("Bonjour, voici une ligne de texte.\n")
    fichier.write("Et voici une deuxième ligne.")

لا تضيف الدالة write() تلقائيًا فاصل سطر في نهاية النص، لذا عليك إضافته صراحةً عند الحاجة باستخدام \n.

إضافة نص إلى ملف موجود

with open("mon_fichier.txt", "a") as fichier:
    fichier.write("\nCette ligne est ajoutée à la fin du fichier.")

كتابة عدة أسطر دفعة واحدة

lignes = ["Ligne 1", "Ligne 2", "Ligne 3"]
with open("mon_fichier.txt", "w") as fichier:
    fichier.writelines(ligne + "\n" for ligne in lignes)

إدارة مسارات الملفات

توفّر الوحدة os.path دوال للتعامل مع مسارات الملفات بطريقة متوافقة مع مختلف أنظمة التشغيل:

import os.path

# Vérifier si un fichier existe
if os.path.exists("mon_fichier.txt"):
    print("Le fichier existe.")

# Vérifier si c'est un fichier ou un répertoire
if os.path.isfile("mon_fichier.txt"):
    print("C'est un fichier.")
if os.path.isdir("mon_dossier"):
    print("C'est un répertoire.")

# Obtenir le chemin absolu
chemin_absolu = os.path.abspath("mon_fichier.txt")
print(chemin_absolu)

# Joindre des parties de chemins
chemin_complet = os.path.join("dossier", "sous_dossier", "fichier.txt")
print(chemin_complet)

وللقيام بعمليات أكثر تقدمًا على مسارات الملفات، توفّر الوحدة pathlib (المتاحة منذ Python 3.4) واجهة أحدث موجّهة بالكائنات:

from pathlib import Path

# Créer un objet Path
chemin = Path("dossier/sous_dossier/fichier.txt")

# Vérifier si le fichier existe
if chemin.exists():
    print("Le fichier existe.")

# Obtenir le répertoire parent
parent = chemin.parent
print(parent)

# Créer un nouveau chemin en joignant
nouveau_chemin = parent / "autre_fichier.txt"
print(nouveau_chemin)

العمل مع ملفات CSV

تُستخدم ملفات CSV (Comma-Separated Values) عادةً لتخزين البيانات الجدولية. توفّر Python الوحدة csv للعمل مع هذه الملفات بسهولة.

قراءة ملف CSV

import csv

with open("donnees.csv", "r", newline="") as fichier_csv:
    lecteur = csv.reader(fichier_csv)
    
    # Lire l'en-tête
    en_tete = next(lecteur)
    print(f"Colonnes : {en_tete}")
    
    # Lire les données
    for ligne in lecteur:
        print(ligne)

قراءة ملف CSV على شكل قاموس

import csv

with open("donnees.csv", "r", newline="") as fichier_csv:
    lecteur = csv.DictReader(fichier_csv)
    
    for ligne in lecteur:
        print(f"Nom: {ligne['nom']}, Âge: {ligne['age']}")

الكتابة في ملف CSV

import csv

donnees = [
    ["Nom", "Âge", "Ville"],
    ["Alice", "30", "Paris"],
    ["Bob", "25", "Lyon"],
    ["Charlie", "35", "Marseille"]
]

with open("personnes.csv", "w", newline="") as fichier_csv:
    ecrivain = csv.writer(fichier_csv)
    ecrivain.writerows(donnees)

الكتابة في ملف CSV باستخدام القواميس

import csv

donnees = [
    {"nom": "Alice", "age": 30, "ville": "Paris"},
    {"nom": "Bob", "age": 25, "ville": "Lyon"},
    {"nom": "Charlie", "age": 35, "ville": "Marseille"}
]

with open("personnes.csv", "w", newline="") as fichier_csv:
    champs = ["nom", "age", "ville"]
    ecrivain = csv.DictWriter(fichier_csv, fieldnames=champs)
    
    ecrivain.writeheader()
    ecrivain.writerows(donnees)

العمل مع ملفات JSON

JSON (JavaScript Object Notation) هو تنسيق خفيف لتبادل البيانات. توفّر Python الوحدة json للعمل مع هذا التنسيق.

قراءة ملف JSON

import json

with open("donnees.json", "r") as fichier_json:
    donnees = json.load(fichier_json)
    print(donnees)

الكتابة في ملف JSON

import json

donnees = {
    "personnes": [
        {"nom": "Alice", "age": 30, "ville": "Paris"},
        {"nom": "Bob", "age": 25, "ville": "Lyon"},
        {"nom": "Charlie", "age": 35, "ville": "Marseille"}
    ]
}

with open("personnes.json", "w") as fichier_json:
    json.dump(donnees, fichier_json, indent=4)  # indent pour un format plus lisible

التعامل مع الملفات الثنائية

تحتوي الملفات الثنائية على بيانات ليست بتنسيق نصي يمكن للإنسان قراءته. تستطيع Python التعامل معها باستخدام الوضع 'b'.

قراءة ملف ثنائي

with open("image.jpg", "rb") as fichier_binaire:
    donnees = fichier_binaire.read()
    print(f"Taille du fichier : {len(donnees)} octets")

الكتابة في ملف ثنائي

donnees_binaires = b'\x00\x01\x02\x03'  # Exemple de données binaires
with open("binaire.bin", "wb") as fichier_binaire:
    fichier_binaire.write(donnees_binaires)

معالجة الاستثناءات أثناء التعامل مع الملفات

عند العمل مع الملفات، من المهم معالجة الاستثناءات التي قد تحدث:

try:
    with open("fichier_inexistant.txt", "r") as fichier:
        contenu = fichier.read()
except FileNotFoundError:
    print("Le fichier n'existe pas.")
except PermissionError:
    print("Vous n'avez pas les permissions nécessaires pour accéder à ce fichier.")
except IsADirectoryError:
    print("C'est un répertoire, pas un fichier.")
except Exception as e:
    print(f"Une erreur inattendue s'est produite : {e}")

التعامل مع المجلدات (الأدلة)

توفّر Python دوال لإنشاء المجلدات وعرض محتوياتها وحذفها.

إنشاء مجلد

import os

# Créer un seul répertoire
os.mkdir("nouveau_dossier")

# Créer des répertoires imbriqués
os.makedirs("parent/enfant/petit-enfant", exist_ok=True)  # exist_ok=True évite l'erreur si le dossier existe déjà

عرض محتوى مجلد

import os

# Lister tous les fichiers et dossiers
contenu = os.listdir("mon_dossier")
print(contenu)

# Obtenir uniquement les fichiers
fichiers = [f for f in os.listdir("mon_dossier") if os.path.isfile(os.path.join("mon_dossier", f))]
print(fichiers)

التنقل في شجرة المجلدات

import os

for dossier_racine, sous_dossiers, fichiers in os.walk("mon_dossier"):
    print(f"Dossier actuel : {dossier_racine}")
    print(f"Sous-dossiers : {sous_dossiers}")
    print(f"Fichiers : {fichiers}")
    print()

استخدام الملفات المؤقتة

تتيح الوحدة tempfile إنشاء ملفات ومجلدات مؤقتة:

import tempfile

# Créer un fichier temporaire
with tempfile.TemporaryFile() as tmp:
    tmp.write(b"Données temporaires")
    tmp.seek(0)  # Retourner au début du fichier
    data = tmp.read()
    print(data)
# Le fichier est automatiquement supprimé

# Créer un répertoire temporaire
with tempfile.TemporaryDirectory() as tmp_dir:
    print(f"Répertoire temporaire créé : {tmp_dir}")
# Le répertoire est automatiquement supprimé

فهم ترميزات الأحرف

عند العمل مع الملفات النصية، يكون ترميز الأحرف مهمًا، خصوصًا للنصوص التي تحتوي على أحرف غير ASCII.

# Spécifier l'encodage lors de l'ouverture du fichier
with open("fichier_utf8.txt", "r", encoding="utf-8") as f:
    texte = f.read()

# Écrire avec un encodage spécifique
with open("nouveau_fichier.txt", "w", encoding="utf-8") as f:
    f.write("Texte avec des caractères spéciaux : éèêà")

من الترميزات الشائعة:

  • 'utf-8' : الترميز الأكثر شيوعًا للويب والأنظمة الحديثة
  • 'latin-1' أو 'iso-8859-1' : ترميز أقدم للغات الغربية
  • 'ascii' : مقتصر على أحرف ASCII (من 0 إلى 127)
  • 'cp1252' : الترميز الافتراضي في Windows للغات الغربية

أفضل الممارسات

  1. استخدم with دائمًا لإدارة الملفات، فهي تضمن إغلاقها حتى في حال حدوث خطأ.
  2. حدّد الترميز عند فتح الملفات النصية لتفادي مشكلات الأحرف الخاصة.
  3. عالج الاستثناءات المتعلقة بالملفات لجعل شيفرتك أكثر متانة.
  4. استخدم المسارات النسبية بدلًا من المسارات المطلقة لضمان قابلية النقل.
  5. فضّل pathlib للتعامل الحديث والموجّه بالكائنات مع مسارات الملفات.
  6. استخدم الوحدات المتخصصة (csv وjson وغيرها) بدلًا من تحليل التنسيقات يدويًا.

الخاتمة

يُعدّ التعامل مع الملفات مهارة أساسية في برمجة Python. وسواء كنت تعمل مع ملفات نصية بسيطة، أو تنسيقات منظّمة مثل CSV وJSON، أو ملفات ثنائية، فإن Python توفّر أدوات متينة ومرنة لتلبية احتياجاتك.

استعرضنا في هذا الدرس أساسيات فتح الملفات وقراءتها وكتابتها، إضافةً إلى تقنيات أكثر تقدمًا للعمل مع مختلف التنسيقات ومعالجة الحالات المعقدة.

في الدرس القادم، سنستكشف المكتبات القياسية في Python، التي تتضمن العديد من الوحدات القوية لمهام متنوعة، بما في ذلك ميزات متقدمة للتعامل مع الملفات.

التعليقات

التعليقات مدعومة عبر GitHub Discussions

سجّل الدخول باستخدام GitHub للمشاركة في النقاش

تم نسخ الرابط!