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


الدرس: خطوة خطوة نحو الدوال (2/2)


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

ضع كودنا في صندوق



انتهى ، المترجم؟

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

الحل ؟ ضع الكود الخاص بنا في ملف يمكننا تشغيله حسب الرغبة ، مثل برنامج حقيقي!

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

دعونا نضع برنامجنا في ملف



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

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


annee = input("Saisissez une année : ")
annee = int(annee)

if annee % 400 == 0 or (annee % 4 == 0 and annee % 100 != 0):
    print("السنة التي تم إدخالها هي سنة كبيسة.")
else:
    print("السنة التي تم إدخالها ليست سنة كبيسة.")
 
حان دورك للعمل الآن ، سأقدم لك بعض الخيوط لكنني لن أضع نفسي في مكانك ، فالجميع يأخذ عاداتهم وفقًا لتفضيلاتهم.

افتح محررًا أساسيًا: تحت Windows ، يُعد برنامج notepad مرشحًا ، أو يتم استبعاد Wordpad أو Word ؛ على Linux ، يمكنك استخدام Vim أو Emacs . أدخل الكود في هذا الملف واحفظه بالملحق  .py (مثال bissextile.py ) ، كما في الشكل التالي. سيسمح هذا لنظام التشغيل بمعرفة أنه يحتاج إلى استخدام Python لتشغيل هذا البرنامج (هذا مطلوب على Windows فقط) .

python
في نظام Linux ، ستحتاج إلى إضافة سطر في ملفك ، في البداية ، لتحديد مسار مترجم Python (إذا كنت قد كتبت بالفعل نصوصًا ، في bash على سبيل المثال ، لن تفاجئك هذه الطريقة ) . السطر الأول من برنامجك سيكون:

#!chemin
 
ثم استبدل المصطلح  chemin بالطريق الذي يتيح الوصول إلى المترجم الفوري ، على سبيل المثال /usr/bin/python3.4 . ستحتاج إلى تغيير إذن التنفيذ للملف قبل تنفيذه كبرنامج نصي.

في Windows ، انتقل إلى المجلد حيث قمت بحفظ ملفك .py . يمكنك النقر فوقه نقرًا مزدوجًا ، وسيعرف Windows أنه يحتاج إلى استدعاء Python باستخدام الامتداد ، .py وتتولى Python المسؤولية. ومع ذلك ، انتظر نظرًا لوجود بعض الأشياء التي يجب تسويتها قبل أن تتمكن من تشغيل برنامجك.

بعض التعديلات


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


# -*-coding:ENCODAGE -*
 
في نظام التشغيل Windows ، ربما تحتاج إلى التغيير إلى ENCODAGE"Latin-1" . في Linux ، سيكون هذا على الأرجح "utf-8" . الآن ليس المكان أو الوقت المناسب لفصل عن الترميزات. ما عليك سوى استخدام السطر الذي يناسبك وستكون بخير.

من المحتمل ، إذا قمت بتشغيل التطبيق الخاص بك بنقرة مزدوجة ، أن يتم إغلاق البرنامج الخاص بك على الفور بعد مطالبتك بالسنة. في الواقع ، يقوم بالحساب ، لكنه يصل إلى نهاية البرنامج في جزء من الثانية ويغلق التطبيق ، لأنه قد انتهى. للتغلب على هذه الصعوبة ، يجب أن تطلب من برنامجك التوقف عند نهاية تنفيذه. سيتعين عليك إضافة تعليمات خاصة إلى حد ما ، مكالمة نظام تعمل تحت Windows (وليس في نظام Linux ) . يجب عليك أولاً استيراد الوحدة os . ثم نضيف الاستدعاء إلى الوظيفةos.system بتمرير المعلمة سلسلة الأحرف " pause  " (هذا ، في نهاية البرنامج الخاص بك).  في نظام Linux ، يمكنك ببساطة تشغيل برنامجك في وحدة التحكم أو ، إذا كنت ترغب في أخذ قسط من الراحة ، فاستخدمه على سبيل المثال input قبل نهاية البرنامج (ولكن ليس أنيقًا جدًا).


# -*-coding:Latin-1 -*

import os # نقوم باستيراد وحدة نظام التشغيل التي تحتوي على متغيرات
           # ووظائف مفيدة للتواصل مع
           # نظام التشغيل
# اختبار البرنامج ما إذا كانت السنة التي أدخلها المستخدم كبيسة أم لا

annee = input("ُEntrez une année : ") # ننتظر حتى يقدم المستخدم بادخال السنة التي يريد اختبارها 
annee = int(annee) # خطر حدوث خطأ إذا لم يقم المستخدم بإدخال رقم

if annee % 400 == 0 or (annee % 4 == 0 and annee % 100 != 0):
    print("السنة التي تم إدخالها هي سنة كبيسة.")
else:
    print("السنة التي تم إدخالها ليست سنة كبيسة.")

# تم إيقاف البرنامج مؤقتًا لمنعه من الإغلاق (Windows)
os.system("pause")
 
يمكنك الآن فتح ملفك bissextile.py، يجب أن يعمل البرنامج بشكل مثالي (الشكل التالي).
python
عندما تقوم بتشغيل هذا البرنامج النصي ، سواء في نظام التشغيل Windows أو Linux ، فأنت تستخدم دائمًا مترجم Python ! لم يتم تجميع برنامجك ، ولكن يتم تنفيذ كل سطر تعليمات سريعًا بواسطة المترجم الفوري ، وهو نفس السطر الذي نفذ برامجك الأولى في مترجم الأوامر. الاختلاف الكبير هنا هو أن Python تقوم بتشغيل برنامجك من الملف ، لذلك إذا كنت تريد تعديل البرنامج ، فسيتعين عليك تعديل الملف.

اعلم أن هناك محررين متخصصين في Python ، بما في ذلك Idle المثبت في نفس وقت Python (أنا شخصياً لا أستخدمه ) يمكنك فتحه بالنقر بزر الماوس الأيمن على ملفك .py ومشاهدة كيفية عمله ، فالأمر ليس بهذا التعقيد ويمكنك حتى تشغيل البرنامج من داخل هذا البرنامج. لكن ، بما أنني لا أستخدمه ، فلن أحاضرك فيه. إذا كنت تواجه مشكلة في استخدام أي من ميزات البرنامج ، فابحث في الإنترنت: يجب أن توجد دروس أخرى باللغة الإنجليزية في أسوأ الأحوال.

لقد جئت لغزو العالم ... وإنشاء وحداتي الخاصة



الوحدات الخاصة بي


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

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

  • ملف multipli.py يحتوي على الوظيفة table التي  قمنا بكتابتها في الفصل السابق ؛
  • ملف test.py يحتوي على اختبار التنفيذ لوحدتنا.
يجب أن تكون على ما يرام مع هذا. لا تنس تحديد السطر الذي يحدد الترميز في رأس الملفين. الآن دعنا نرى رمز الملف multipli.py .

""" وحدة المضاعف التي تحتوي على وظيفة الجدول """

def table(nb, max=10):
    """ دالة تعرض جدول الضرب بعدد من 
    1 * nb حتى max * nb"""
    i = 0
    while i < max:
        print(i + 1, "*", nb, "=", (i + 1) * nb)
        i += 1
 
نحن فقط نحدد وظيفة واحدة table، والتي تعرض جدول الضرب المختار. لا شيء جديد حتى الآن. إذا كنت تتذكر تلك docstrings التي تحدثنا عنها في الفصل السابق ، فسترى أننا أدخلنا واحدة جديدة هنا ، ليس للتعليق على وظيفة بل على وحدة كاملة. إنها عادة جيدة أن نأخذها عندما تكبر مشاريعنا.

هذا هو رمز الملف test.py، لا تنس السطر الذي يحدد الترميز الخاص بك ، في رأس الملف.


import os
from multipli import *

table(3, 20)
os.system("pause")
 
من خلال إطلاقه مباشرة ، هذا ما نحصل عليه:

1 * 3 = 3
2 * 3 = 6
3 * 3 = 9
4 * 3 = 12
5 * 3 = 15
6 * 3 = 18
7 * 3 = 21
8 * 3 = 24
9 * 3 = 27
10 * 3 = 30
11 * 3 = 33
12 * 3 = 36
13 * 3 = 39
14 * 3 = 42
15 * 3 = 45
16 * 3 = 48
17 * 3 = 51
18 * 3 = 54
19 * 3 = 57
20 * 3 = 60
اضغط على أى زر للاستمرار ...
 
لا أعتقد أن لدي الكثير لأضيفه. لقد رأينا كيفية إنشاء وحدة ، ما عليك سوى وضعها في ملف. يمكن بعد ذلك استيراده من ملف آخر موجود في نفس الدليل عن طريق تحديد اسم الملف (بدون الامتداد .py ) . الكود الخاص بنا ، مرة أخرى ، ليس مفيدًا جدًا ولكن يمكنك تعديله لجعله أكثر إثارة للاهتمام ، فأنت ضليع به الآن.

عند استيراد الوحدة النمطية الخاصة بك ، ستقرأ Python ملفًا (أو تنشئه إذا لم يكن موجودًا) .pyc . بدءًا من الإصدار 3.2 ، يوجد هذا الملف في مجلد __pycache__ .

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

قم بإجراء اختبار الوحدة النمطية في الوحدة نفسها


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

لنأخذ كود الوحدة multipli:


"""module multipli contenant la fonction table"""

def table(nb, max=10):
    """ nb دالة تعرض جدول الضرب عدد """
    i = 0
    while i < max:
        print(i + 1, "*", nb, "=", (i + 1) * nb)
        i += 1
 
تحدد هذه الوحدة وظيفة واحدة table، والتي قد يكون من الجيد اختبارها. نعم ولكن ... إذا أضفنا سطرًا أدناه مباشرةً ، على سبيل المثال table(8)، فسيتم تنفيذ هذا السطر أثناء الاستيراد ، وبالتالي ، في البرنامج الذي يستدعي الوحدة. عندما تفعل ذلك import multipli، سترى جدول الضرب في 8 معروضًا ... حسنًا ،.

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


"""module multipli contenant la fonction table"""

import os

def table(nb, max=10):
    """nb دالة تعرض جدول الضرب بعدد   
    1 * nb حتى max * nb"""
    i = 0
    while i < max:
        print(i + 1, "*", nb, "=", (i + 1) * nb)
        i += 1


if __name__ == "__main__":
    table(4)
    os.system("pause")
 
لا تنس السطر الذي يشير إلى الترميز!

هنا. الآن ، إذا قمت بالنقر نقرًا مزدوجًا فوق الملف مباشرةً multipli.py ، فسترى جدول الضرب بمقدار 4. ومع ذلك ، إذا قمت باستيراده ، فلن يتم تنفيذ كود الاختبار. كل شيء يعتمد في الواقع على المتغير __name__، إنه متغير موجود عند بدء تشغيل المترجم. إذا تم تعيينه __main__، فهذا يعني أن الملف المستدعى هو الملف المنفذ. بمعنى آخر ، إذا كان الأمر __name__يستحق __main__، يمكنك وضع رمز سيتم تنفيذه إذا تم تشغيل الملف مباشرة كملف تنفيذي.

خذ الوقت الكافي لفهم هذه الآلية ، وقم بإجراء الاختبارات إذا لزم الأمر ، فقد يكون ذلك مفيدًا لك لاحقًا.

الحزم (packages)



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

نظريا

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

عمليا


في الممارسة العملية ، الحزم… أدلة! يمكن أن يكون فيها أدلة أخرى (حزم أخرى) أو ملفات (وحدات).

مثال على التسلسل الهرمي


بالنسبة لمكتبتنا التخيلية ، سيبدو التسلسل الهرمي للدليل والملف كما يلي:

  • دليل باسم المكتبة يحتوي على:
    • دليل evenementsيحتوي على:
      • وحدة نمطية keyboard .
      •  وحدة نمطية mouse .
      • ...
    • دليل  effets يحتوي على مؤثرات بيانية مختلفة ؛
    • دليل  objets يحتوي على الكائنات الرسومية المختلفة لنافذتنا (الأزرار ، مناطق النص ، أشرطة القوائم ، إلخ).

حزم الاستيراد


إذا كنت ترغب في استخدام المكتبة الوهمية التي رأيناها للتو في برنامجك ، فلديك العديد من الوسائل التي تدور جميعها حول الكلمات الرئيسية from و import :


import name_library
 
هذا الخط يستورد الحزمة التي تحتوي على المكتبة. للوصول إلى الحزم الفرعية ، ستستخدم فترة ". لنمذجة المسار إلى الوحدة النمطية أو الوظيفة التي تريد استخدامها:

name_library.evenements # يشير إلى حزمة الأحداث الفرعية
name_library.evenements.keyboard # keyboard يشير إلى حزمة الأحداث 
 
إذا كنت ترغب فقط في استيراد وحدة نمطية واحدة (أو وظيفة واحدة) من حزمة ، فستستخدم بنية مشابهة وسهلة الاستخدام:

from name_library.objets import bouton
 
بناءً على احتياجاتك ، يمكنك أن تقرر استيراد حزمة كاملة أو حزمة فرعية أو حزمة فرعية ... أو مجرد وحدة نمطية أو حتى وظيفة واحدة. سوف يعتمد على احتياجاتك.

قم بإنشاء حزمك الخاصة


إذا كنت تريد إنشاء الحزم الخاصة بك ، فقم أولاً بإنشاء دليل باسم الحزمة في نفس المجلد مثل برنامج Python الخاص بك.

في هذا الدليل ، يمكنك إما:

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

ملف التهيئة


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

مثال أخير


إليك مثال أخير ، يمكنك القيام به هذا الوقت في نفس الوقت الذي أفعله للتأكد من أنه يعمل.

في دليل الكود الخاص بك ، حيث تضع أمثلة Python الخاصة بك ، قم بإنشاء ملف .pyستتصل به test_package.py.

قم بإنشاء مجلد في نفس الدليل package . في ذلك ، قم بإنشاء ملف  fonctions.pyستقوم فيه بنسخ وظيفتك table .

في ملفك test_package.py، إذا كنت تريد استيراد وظيفتك table، فلديك عدة حلول:


from package.fonctions import table
table(5) # استدعاء الوظيفة 

# أو ...
import package.fonctions
package.fonctions.table(5)  # استدعاء الوظيفة
 
هنا. لا يزال هناك الكثير لتقوله عن الحزم ، لكنني أعتقد أنك رأيت الأساسيات. سيكشف هذا التفسير الصغير أهميته عندما يتعين عليك إنشاء برامج كبيرة إلى حد ما. تجنب وضع كل شيء في وحدة واحدة دون محاولة تحديد الأولويات ، واستفد من هذه الإمكانية التي توفرها Python .

باختصار


  • يمكن كتابة برامج Python في ملفات ذات الامتداد .py .
  • يمكنك إنشاء ملفات تحتوي على وحدات لفصل الكود.
  • يمكنك إنشاء أدلة تحتوي على حزم لتحديد أولويات البرنامج.