لقد تعلمت بالفعل أنه ليس من الملائم كتابة برامج أطول في
مفسر بايثون - وحدة تحكم بايثون التفاعلية (Python interactive console)- وكنت تكتب نصوص بايثون الخاصة بك كـ
ملفات نصية بامتداد .py
.
يمكن تعديل النصوص وتنفيذها بشكل متكرر بسهولة. يعمل هذا بشكل جيد حتى النقطة التي يصبح فيها من المحدود جدًا الاحتفاظ بكل التعليمات البرمجية الخاصة بنا في ملف واحد (على سبيل المثال، يصبح النص طويلًا جدًا، وتتكرر أجزاء من التعليمات البرمجية في نصوص مختلفة).
هل يمكننا تنظيم التعليمات البرمجية الخاصة بنا بشكل أفضل من ذلك؟
يسمح لنا بايثون بتنظيم التعليمات البرمجية في وحدات (modules). الوحدة (module) هي شيء مثل صندوق يحتوي على بعض التعليمات البرمجية الجاهزة للاستخدام. يمكننا سحبها من الرف، استيرادها (import)، ثم استخدامها في النص الخاص بنا.
على سبيل المثال، يمكنك استيراد الدالة (function) sqrt
من
الوحدة (module) math
:
from math import sqrt
print(sqrt(2))
في هذه الحالة، الوحدة (module) math
(مكتبة بايثون القياسية - Python standard library)
تحتوي على مجموعة من الدوال (functions) والثوابت الرياضية المختلفة.
باستخدام الأمر<from <module> import <names
قمنا بسحب دالة واحدة sqrt
من
وحدات math
، والتي تشير
إلى الدالة التي تحسب الجذر التربيعي،
وجعلناها متاحة في برنامجنا.
بدلاً من ذلك، يمكنك استيراد وحدة (module) كاملة والوصول إلى أسمائها من خلال
اسم الوحدة (module) والنقطة (.)
، على سبيل المثال:
import math
print(math.cos(math.pi))
... أو:
import turtle
turtle.left(90)
turtle.color('red')
turtle.forward(100)
turtle.exitonclick()
تسمح بايثون بنوع خاص من الوحدات (modules) التي تحتوي بدورها على وحدات فرعية (sub-modules). تسمى الوحدة (module) التي هي عبارة عن مجموعة من الوحدات (modules) حزمة (package) في مصطلحات بايثون. يمكن أن تحتوي الحزمة (package) على حزم فرعية (sub-packages)، وفي المشاريع الأكثر تعقيدًا، من الشائع أن يكون هناك عدة مستويات من الوحدات الفرعية (sub-modules).
لا تخف! لا يختلف استيراد وحدة فرعية (sub-module) من حزمة (package) عن الوحدة (module) العادية ذات المستوى الأعلى. يتم فصل الوحدات الفرعية (sub-modules) بنقاط، ولكن بصرف النظر عن ذلك، فإنك تعمل معها بنفس الطريقة:
import os # os هي حزمة (package)
import os.path # path هي وحدة فرعية (submodule) من حزمة os، os.path هو اسم وحدة كامل (full module name)
directory = "./test"
if not os.path.exists(directory):
os.mkdir(directory)
يمكنك أيضًا إنشاء وحدتك (module) الخاصة، ببساطة عن طريق إنشاء ملف بايثون. ستكون الدوال والمتغيرات (والكائنات المسماة الأخرى) التي تنشئها هناك متاحة في البرامج التي تستورد هذه الوحدة (module) فيها.
هيا نجربها. أولاً، قم بإنشاء ملف بايثون جديد باسم meadow.py
واكتب:
meadow_colour = 'green'
number_of_kitties = 28
def description():
return 'The meadow is {colour}. There are {number} kitties.'.format(
colour=meadow_colour, number=number_of_kitties)
ثم اكتب في ملف آخر باسم write.py
بالمحتوى التالي:
import meadow
print(meadow.description())
وقم بتشغيل:
$ python3 write.py
تبحث بايثون عن الوحدات المستوردة (imported modules) بترتيب محدد على النحو التالي:
مدمجة
(built-in) من مكتبة بايثون القياسية (Python Standard Library) (مثل sys و math)sys.path
، والذي يكون افتراضيًا نفس المجلد حيث يوجد النص قيد التنفيذ (وليس مجلد العمل الحالي - حيث تم تشغيل أمر بايثون)PYTHONPATH
لا تنسَ وجود كلا الملفين (meadow.py و write.py) في نفس المجلد.
ماذا يفعل الأمر import meadow
بالضبط؟
أولاً، تبحث بايثون عن ملف مطابق (meadow.py
) وتقوم بتشغيل جميع الأوامر
في الملف، من الأعلى إلى الأسفل، كما لو كان نصًا عاديًا.
بمجرد الانتهاء، يتم حفظ جميع الأسماء في النطاق العام (المتغيرات والدوال،
إلخ) وجعلها متاحة للاستخدام خارج الوحدة (module).
عند محاولة استيراد نفس الوحدة (module) مرة أخرى، لا يتم تنفيذ الأوامر الموجودة في الوحدة وتعيد بايثون استخدام الوحدة التي تم تهيئتها بالفعل.
جربها! اكتب في نهاية meadow.py
:
print('The meadow is green!')
ثم قم بتشغيل python
في سطر الأوامر (إذا كان لديك بالفعل مترجم بايثون تفاعلي
مفتوح، أغلقه، وقم بتشغيله مرة أخرى) وأدخل:
>>> import meadow
The meadow is green!
>>> import meadow
>>> import meadow
>>>
تظهر الرسالة التي نطبعها في نهاية الوحدة (module) مرة واحدة فقط.
عندما تقوم الوحدة (module) بـ "فعل شيء ما" (تطبع شيئًا، أو تسأل المستخدم،
تكتب شيئًا في ملف)، نقول إن لها تأثيرًا جانبيًا (side effect).
نسعى عمومًا لتجنب كتابة وحدات ذات آثار جانبية.
الغرض من الوحدة (module) هو تزويدنا بـ دوال (functions)، والتي
سنستخدمها لفعل شيء ما، وليس فعلها بدلاً منا.
على سبيل المثال، عندما نكتب import turtle
، لا تفتح نافذة. تفتح
فقط عندما نكتب ()turtle.forward
.
لذا من الأفضل حذف أمر print
من وحدتنا (module).
من الآن فصاعدًا، سنعمل على مشاريع أكبر تحتوي على المزيد من الملفات. نوصي بإنشاء مجلد لكل منهم.
import
(The import
best practice)عمليات استيراد بايثون حساسة لحالة الأحرف. import Spam
يختلف عن import spam
.
احتفظ دائمًا بعمليات الاستيراد في أعلى النص الخاص بك قبل بدء التعليمات البرمجية الخاصة بك.
بشكل عام، ترتيب عمليات الاستيراد غير مهم. على الرغم من ذلك، غالبًا ما نقوم بترتيب عمليات الاستيراد،
1) وحدات من مكتبة نظام بايثون (Python system library) (مثل math
)
2) مكتبات الطرف الثالث (third-party libraries) (المثبتة باستخدام أمر pip
)
3) عمليات استيراد من وحداتنا الخاصة
إذا قررت استيراد عدة أسماء من الوحدة (module)، فافعل ذلك في أمر استيراد واحد، على سبيل المثال:
from math import pi, sin, cos
يمكنك العثور على مزيد من المعلومات حول الاستيراد والوحدات هنا.