تعلم البرمجة مع Python


الدرس: استخدام الملفات


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

سننهي هذا الفصل بمعرفة كيفية حفظ كائناتنا في ملفات ، من أجل استخدامها من جلسة إلى أخرى من برنامجنا.

قبل البدء



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

لكن أولاً ، لماذا تقرأ أو تكتب في الملفات؟


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

إذا تمكنا ، في TP  ZCasino ، من توفير المبلغ الذي كان لدينا في جيبنا عند مغادرة الكازينو ، كان بإمكاننا الرد دون أن نبدأ من الصفر.

قم بتغيير دليل العمل الحالي


إذا كنت تريد العمل في مترجم Python ، وأنا أشجعك على القيام بذلك ، فستحتاج إلى تغيير دليل العمل الحالي. في الواقع ، عند بدء تشغيل المترجم الفوري ، يكون دليل العمل الحالي هو الدليل الذي يوجد فيه الملف التنفيذي للمترجم. على نظام Windows ، يكون C:\Python3X X مختلفًا اعتمادًا على إصدار Python الخاص بك. على أي حال ، أدعوك لتغيير دليل العمل الحالي. لهذا تحتاج إلى استخدام وظيفة الوحدة os ، والتي تسمى chdir (Change Directory ) .


>>> import os
>>> os.chdir("C:/tests python")
>>>
 
لكي يعمل هذا البيان ، يجب أن يكون الدليل موجودًا. قم بتعديل السلسلة التي تم تمريرها في المعلمة os.chdir وفقًا للمجلد الذي تريد نقله.

أنصحك ، سواء كنت تستخدم نظام التشغيل Windows أم لا ، باستخدام الرمز / لوصف المسار.

يمكنك استخدام ، عند المضاعفة ، الشرطة المائلة للخلف \\ ولكن إذا نسيت مضاعفتها ، فستحصل على أخطاء. لذا أنصحك باستخدام الشرطة المائلة / ، فهي تعمل بشكل جيد حتى على Windows .

عندما تبدأ تشغيل برنامج Python مباشرة ، على سبيل المثال بالنقر المزدوج عليه ، فإن الدليل الحالي هو المكان الذي تبدأ فيه البرنامج. إذا كان لديك ملف mon_programme.py موجود على القرص C:، فسيكون دليل العمل الحالي عند بدء تشغيل البرنامج C:\ .

المسارات النسبية والمطلقة


لوصف هيكل شجرة النظام ، هناك احتمالان:

  • مسارات مطلقة
  • المسارات النسبية.

المسار المطلق

عندما نصف هدفًا (ملف أو دليل) في شكل مسار مطلق ، فإننا نصف تسلسل الأدلة المؤدية إلى الملف. تحت Windows ، سنبدأ من اسم المجلد (  C:\، D:\... ) . في أنظمة Unix ، من المرجح أن يكون هذا من /  .
على سبيل المثال ، ضمن Windows ، إذا كان لدينا ملف مسمى fic.txt ، موجود في مجلد test، موجود هو نفسه على القرص  C:، فسيكون المسار المطلق المؤدي إلى ملفنا C:\test\fic.txt .

المسار النسبي


عندما نصف موضع ملف بمسار نسبي ، فهذا يعني أننا نأخذ في الاعتبار المجلد الذي نحن فيه حاليًا. وبالتالي ، إذا كنا في المجلد C:\test وأردنا الوصول إلى الملف fic.txt الموجود في هذا المجلد نفسه ، فسيكون المسار النسبي المؤدي إلى هذا الملف هو ببساطة fic.txt .

الآن ، إذا كنا في C: ، فسيكون طريقنا النسبي test\fic.txt .

عند وصف مسار نسبي ، نستخدم أحيانًا الرمز ..الذي يعين الدليل الأصلي. هذا مثال جديد:

  • :C
    • test
      • rep1
        • fic1.txt
      • rep2
        • fic2.txt
        • fic3.txt
    هو في ملفنا test أن كل شيء يحدث. لدينا دليلين فرعيين باسم rep1 و rep2 . في rep1 لدينا ملف واحد :  fic1.txt . في rep2، لدينا ملفان :  fic2.txt و fic3.txt .

    إذا كان دليل العمل الحالي هو دليل العمل الحالي rep2 ونريد الوصول إليه fic1.txt ، فسيكون المسار النسبي لدينا ..\rep1\fic1.txt .

    أنا أستخدم الخطوط المائلة العكسية هنا لأن شجرة العينة عبارة عن قالب Windows وهذه هي الفواصل المستخدمة لوصف شجرة Windows . لكن ، في التعليمات البرمجية الخاصة بك ، ما زلت أنصحك باستخدام شرطة مائلة (/) .

    ملخص


    لذلك فإن المسارات المطلقة والنسبية هما طريقتان لوصف المسار المؤدي إلى الملفات أو الدلائل. ولكن ، إذا كانت النتيجة هي نفسها ، فإن الوسائل المستخدمة ليست متطابقة: عندما نستخدم مسارًا مطلقًا ، فإننا نصف المسار بأكمله المؤدي إلى الملف ، بغض النظر عن مكان وجودنا. يسمح المسار المطلق بالوصول إلى موقع على القرص بغض النظر عن دليل العمل الحالي. الجانب السلبي لهذه الطريقة هو أنه عليك أن تعرف مسبقًا مكان وجود الملفات التي تحتاجها على القرص.

    يصف المسار النسبي تسلسل الدلائل المراد اجتيازها من خلال اتخاذ نقطة أصل ليس الجذر أو المحيط الذي يتم تخزين الهدف عليه ، ولكن الدليل الذي يوجد فيه أحد. هذا له بعض المزايا عندما تقوم بتشفير مشروع ، لا يتعين عليك معرفة مكان تخزين المشروع لبناء أدلة متعددة. لكن هذا ليس بالضرورة الحل الأفضل في جميع الظروف.

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

    os.getcwd()(CWD = « Current Working Directory »).

    لذلك يجب أن يكون هذا كافيا بالنسبة لك. بالنسبة للعروض التوضيحية التالية ، استخدم os.chdir دليل الاختبار الذي تم إنشاؤه لهذه المناسبة.

القراءة والكتابة في ملف



سنبدأ القراءة قبل الكتابة في ملف. على سبيل المثال ، أدعوك لإنشاء ملف في دليل العمل الحالي الذي اخترته. أنا في حاجة ماسة إلى الإلهام ، سأتصل به fichier.txt وأكتب فيه ، باستخدام محرر غير منسق ( مثل Windows Notepad )

" C'est le contenu du fichier. Spectaculaire non ? "

فتح الملف


أولاً ، نحتاج إلى فتح الملف باستخدام Python . للقيام بذلك ، نستخدم الوظيفة open المتاحة دون الحاجة إلى استيراد أي شيء. يأخذ كمعلمة:

  • المسار (المطلق أو النسبي) المؤدي إلى فتح الملف ؛
  • وضع الافتتاح.
يتم إعطاء الوضع في شكل سلسلة أحرف. فيما يلي الأوضاع الرئيسية:
  • 'r' : قراءة الافتتاح (read).
  • 'w' : مفتوح للكتابة (write). يتم الكتابة فوق محتويات الملف. إذا لم يكن الملف موجودا، يتم إنشاؤه.
  • 'a' : مفتوح للكتابة في وضع الإلحاق. نكتب في نهاية الملف دون الكتابة فوق المحتوى القديم للملف. إذا لم يكن الملف موجودا، يتم إنشاؤه.
يمكننا أن نضيف إلى كل هذه الأوضاع علامة b لفتح الملف في الوضع الثنائي. سنرى فائدته لاحقًا ، إنه وضع خاص إلى حد ما.

هنا نريد قراءة الملف. لذلك سوف نستخدم الوضع 'r' .


>>> mon_fichier = open("fichier.txt", "r")
>>> mon_fichier
<_io.TextIOWrapper name='fichier.txt' encoding='cp1252'>
>>> type(mon_fichier)
<
قد يكون الترميز المحدد عند عرض الملف في المترجم مختلفًا جدًا اعتمادًا على نظامك. هنا ، أنا أعمل في مترجم Python في Windows ، وبالتالي فإن الترميز المختار هو ترميز Windows خاص بوحدة التحكم. لا تتفاجأ إذا كان الأمر مختلفًا معك.

لذلك تقوم الوظيفة Open بإنشاء ملف. تقوم بإرجاع كائن من الفئة TextIoWrapper . بعد ذلك ، سنستخدم طرقًا من هذا الفصل للتفاعل مع الملف.

يجب أن يفاجئك نوع الكائن إلى حد ما. كان من الممكن أن من نوع file بعد كل شيء. في الواقع  open يفتح الملف، ولكن TextIoWrapper يتم استخدامها في ظروف أخرى، على سبيل المثال لعرض النص على الشاشة. حسنًا ، هذا لا يشغلنا كثيرًا هنا ، لن أسهب في الحديث عنه.

class '_io.TextIOWrapper'> >>>

إغلاق الملف


تذكر إغلاق ملف بعد فتحه. إذا كانت هناك تطبيقات أخرى ، أو أجزاء أخرى من التعليمات البرمجية الخاصة بك ، تريد الوصول إلى هذا الملف ، فلن يتمكنوا من ذلك لأن الملف سيكون مفتوحًا بالفعل. هذا صحيح بشكل خاص في الكتابة ، لكن تعلم العادات الجيدة. طريقة الاستخدام هي  close :


>>> mon_fichier.close()
>>>
 

اقرأ الملف بالكامل


للقيام بذلك ، نستخدم طريقة read الفصل TextIoWrapper . تقوم بإرجاع الملف بأكمله:


>>> mon_fichier = open("fichier.txt", "r")
>>> contenu = mon_fichier.read()
>>> print(contenu)
C'est le contenu du fichier. Spectaculaire non ?
>>> mon_fichier.close()
>>>
 
ما الذي يمكن أن يكون أبسط؟ تقوم الطريقة read بإرجاع كل محتويات الملف ، والتي يتم التقاطها في سلسلة أحرف. لا يحتوي ملفنا على فاصل أسطر ، ولكن إذا كان يحتوي على فاصل أسطر ، فسيكون لديك في المتغير الخاص بك contenu الإشارات التي \nتشير إلى فاصل سطر.

الآن بعد أن أصبح لديك سلسلة ، يمكنك بالطبع فعل كل شيء: تحويلها ، كليًا أو جزئيًا ، إذا لزم الأمر ، split السلسلة لتصفح كل سطر ومعالجتها ... باختصار ، كل شيء ممكن.

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


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

اكتب سلسلة


للكتابة إلى ملف ، نستخدم الطريقة write بتمريرها كمعامل وهي السلسلة التي نكتبها إلى الملف. تقوم بإرجاع عدد الأحرف التي تمت كتابتها. نحن بطبيعة الحال غير ملزمين باسترداد هذه القيمة ، إلا إذا كنا في حاجة إليها.


>>> mon_fichier = open("fichier.txt", "w") # لقد سحقت كل شيء!
>>> mon_fichier.write("Premier test d'écriture dans un fichier via Python")
50
>>> mon_fichier.close()
>>>
 
يمكنك التحقق من أن ملفك يحتوي على النص المكتوب هناك.

اكتب أنواع أخرى من البيانات


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

Os تحتوي الوحدة على الكثير من الوظائف الرائعة لإنشاء وحذف الملفات والدلائل. سأدعك تلقي نظرة على المساعدة إذا كنت مهتمًا.

الكلمة with


لا تيأس ، ليس لدينا الكثير من الكلمات الرئيسية لاكتشافها ... ولكن مع ذلك عدد قليل. وحتى البعض الذي لن أتحدث عنه ...

نحن لسنا في مأمن من الخطأ. خاصة عند العمل مع الملفات. يمكن أن تحدث أخطاء عند القراءة وعند الكتابة ... وإذا لم تكن حريصًا ، فسيظل الملف مفتوحًا.

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

هناك كلمة أساسية تمنع هذا الموقف with . ها هو تركيبها:


with open(mon_fichier, mode_ouverture) as variable:
    # عمليات الملف
 
نجد بالترتيب:
  • الكلمة الأساسية with ، مقدمة للكتلة التي سنتعامل فيها مع ملفنا. يمكننا أن نجد with في التلاعب بأشياء أخرى لكننا لن نراها هنا.
  • هدفنا. هنا ، نسمي من  open سيعيد كائنًا TextIOWrapper (ملفنا ) .
  • الكلمة الأساسية as التي رأيناها بالفعل في آلية الاستيراد وفي الاستثناءات. إنها تعني دائمًا نفس الشيء: "مثل" .
  • متغيرنا الذي سيحتوي على كائننا. إذا كان المتغير غير موجود ، تقوم بايثون بإنشائه.
مثال ؟

>>> with open('fichier.txt', 'r') as mon_fichier:
...     texte = mon_fichier.read()
... 
>>>
 
هذا لا يعني أن كتلة البيان لن تطرح أي استثناءات.

هذا يعني فقط أنه في حالة حدوث استثناء ، فسيظل الملف مغلقًا في نهاية الكتلة.

تُستخدم الكلمة الأساسية with لإنشاء "مدير سياق" يتحقق من فتح الملف وإغلاقه ، حتى إذا حدثت أخطاء أثناء الحظر. علاوة على ذلك ، سترى كائنات أخرى تستخدم نفس الآلية.

يمكنك الاتصال  mon_fichier.closed للتحقق من أن الملف مغلق. إذا تم إغلاق الملف ، mon_fichier.closed سيكون من المفيد True .

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

اذهب! قم بتوجيه الوحدة pickle ، حيث سنتعلم كيفية حفظ كائناتنا في ملفات.

حفظ الكائنات في الملفات



في العديد من اللغات عالية المستوى ، يمكنك حفظ العناصر الخاصة بك في ملف. بايثون ليست استثناء. بفضل الوحدة pickle التي سنكتشفها ، يمكننا حفظ أي كائن واستعادته لاحقًا ، في المرة التالية التي يتم فيها تشغيل البرنامج ، على سبيل المثال. بالإضافة إلى ذلك ، يمكن قراءة الملف الناتج من أي نظام تشغيل (بشرط ، بالطبع ، أنه يدعم Python ) .

حفظ كائن في ملف


بالطبع ، نحتاج أولاً إلى استيراد الوحدة  pickle .


>>> import pickle
>>>
 
سنستخدم بعد ذلك فصلين مضمنين في هذه الوحدة: الفصل Pickler والفصل Unpickler .

هذا هو أول ما يهمنا في هذا القسم.

لإنشاء كائننا Pickler ، سنسميه عن طريق تمرير الملف الذي سنحفظ فيه كائننا كمعامل.


>>> with open('donnees', 'wb') as fichier:
...     mon_pickler = pickle.Pickler(fichier)
...     # الحفظ...
... 
>>>
 
عندما نذهب لحفظ كائناتنا ، سيكون في الملف donnees . لم أعطيها تمديدًا ، يمكنك فعل ذلك. لكن تجنب تحديد امتداد يستخدمه البرنامج.

لاحظ وضع الفتح: يتم فتح الملف donnees في وضع الكتابة الثنائية. يكفي أن نضيف ، خلف الحرف الذي يرمز للوضع ، الحرف b للإشارة إلى الوضع الثنائي.

لن يكون الملف الذي ستكتبه بايثون سهل القراءة إذا حاولت فتحه ، لكن هذا ليس هو الهدف.

جيد. الآن بعد أن تم إنشاء أداة التجميع الخاصة بنا ، سنحفظ كائنًا واحدًا أو أكثر في ملفنا. هناك ، الأمر متروك لك لترى كيف تريد تنظيم نفسك ، كما أن الأمر يعتمد كثيرًا على المشروع. أنا اعتدت على حفظ كائن واحد فقط لكل ملف ، لكن لا يوجد أي التزام.

نستخدم طريقة  dump pickler لتسجيل الكائن. استخدامه بسيط للغاية:


>>> score = {
...   "joueur 1":    5,
...   "joueur 2":   35,
...   "joueur 3":   20,
...   "joueur 4":    2,
>>> }
>>> with open('donnees', 'wb') as fichier:
...     mon_pickler = pickle.Pickler(fichier)
...     mon_pickler.dump(score)
... 
>>>
 
بعد تشغيل هذا الكود ، لديك ملف في مجلد الاختبار الخاص بك donnees يحتوي على ... حسنًا ، قاموسنا يحتوي على نتائج لاعبينا الأربعة. إذا كنت تريد تسجيل كائنات متعددة ، فاستدع الطريقة مرة أخرى dump باستخدام الكائنات لتسجيلها. ستتم إضافتهم إلى الملف بالترتيب الذي تحفظهم فيه.

استعادة كائناتنا المسجلة


سوف نستخدم فئة أخرى محددة في الوحدة الخاصة بنا pickle . هذه المرة ، منطقيًا ، إنها فئة Unpickler .

لنبدأ بإنشاء موضوعنا. عندما يتم إنشاؤه ، نمرره الى الملف الذي سنقرأ الكائنات فيه. نظرًا لأننا سنقرأ ، فإننا نغير الوضع ، ونعود إلى الوضع r، وحتى rb لأن الملف ثنائي.


>>> with open('donnees', 'rb') as fichier:
...     mon_depickler = pickle.Unpickler(fichier)
...     # قراءة الكائنات الموجودة في الملف ...
... 
>>>
 
لقراءة الكائن في  ملفنا  ، يجب أن نستدعي طريقة load من depickler . تقوم بإرجاع الكائن الأول الذي تمت قراءته (إذا كان هناك أكثر من عنصر واحد ، فيجب استدعاؤه أكثر من مرة).


>>> with open('donnees', 'rb') as fichier:
...     mon_depickler = pickle.Unpickler(fichier)
...     score_recupere = mon_depickler.load()
... 
>>>
 
وبعد هذا الاستدعاء ، إذا أمكن قراءة الملف ، في المتغير الخاص بك score_recupere، ستحصل على قاموسك يحتوي على الدرجات. هناك ، ربما يكون الأمر غير مألوف ، ولكن عند استخدام هذه الوحدة لحفظ الكائنات التي سيتم الاحتفاظ بها أثناء عدم تشغيل برنامجك ، فهي عملية للغاية بصراحة.

باختصار


  • يمكنك فتح ملف باستخدام الوظيفة التي open تأخذ المسار إلى الملف ووضع الفتح كمعلمات.
  • يمكننا القراءة من ملف باستخدام الطريقة read .
  • يمكننا الكتابة في ملف باستخدام الطريقة write .
  • يجب إغلاق الملف بعد الاستخدام باستخدام الطريقة close .
  • يتم استخدام الوحدة Pickle لحفظ كائنات Python في الملفات ثم إعادة تحميلها.