١. نظرة عامة على عبارات الاستيراد واستيراد المسارات النسبية في بايثون
عند كتابة البرامج في بايثون، تستخدم عبارات import لإعادة استخدام الوحدات بفعالية. في هذه العبارة import، يكون استيراد المسارات النسبية مفيدًا بشكل خاص عندما تكون هناك تبعيات مرنة بين الوحدات. يشرح هذا المقال كيفية استخدام المسارات النسبية في عبارات import في بايثون ومزاياها.
ما هو استيراد المسار النسبي؟
استيراد المسار النسبي هو طريقة لاستيراد وحدات أخرى بناءً على موقع الوحدة الحالية. يكون مفيدًا بشكل خاص للمشاريع الكبيرة أو لتطوير الحزم التي تحتوي على عدة وحدات. يوضح استيراد المسارات النسبية التبعيات بين الوحدات، مما يجعل صيانة المشروع أسهل.
على سبيل المثال، افترض أن لديك بنية دليل كما يلي.
project/
├── main.py
├── package/
│ ├── module_a.py
│ └── sub_package/
│ └── module_b.py
لاستيراد module_a.py من module_b.py باستخدام مسار نسبي، يمكنك كتابة:
from ..module_a import some_function
بهذه الطريقة، يتيح لك استخدام المسارات النسبية استيراد الوحدات بمرونة بناءً على هيكلية الدليل.

٢. الفرق بين المسارات النسبية والمسارات المطلقة
هناك نوعان من عبارات import في بايثون: المسارات النسبية والمسارات المطلقة. يكمن الفرق بينهما في طريقة تحديد الوحدة المستهدفة.
استيراد المسار المطلق
استيراد المسار المطلق يحدد الوحدة بدءًا من جذر المشروع.
على سبيل المثال، في مشروع به البنية التالية، إذا أردت استيراد module_a.py إلى main.py باستخدام مسار مطلق، ستكتب ذلك كما يلي:
from package.module_a import some_function
هذه الطريقة مفيدة عندما يكون هيكل المشروع واضحًا وموقع الوحدات ثابتًا.
استيراد المسار النسبي
من ناحية أخرى، يستورد استيراد المسار النسبي الوحدات بناءً على موقع الوحدة الحالية. يمكن أن تكون المسارات النسبية مرنة نسبيًا، خاصةً عندما يتغير هيكل المشروع. هذا يجعل من الممكن تحسين قابلية إعادة استخدام الشيفرة مع الحفاظ على التبعيات بين الوحدات.
على سبيل المثال، يوضح الكود التالي كيفية استيراد وحدة تقع دليلًا واحدًا فوق الوحدة الحالية:
from ..module_a import some_function
يعتمد الاختيار بينهما على حجم وتعقيد المشروع. بشكل عام، تكون استيرادات المسار المطلق مناسبة عندما يكون موقع الوحدات ثابتًا، بينما تكون استيرادات المسار النسبي أكثر ملاءمة عندما تحدث تغييرات متكررة.
٣. الاستيراد باستخدام المسارات النسبية
استيراد الوحدات من نفس الدليل
عند استيراد وحدة موجودة في نفس الدليل، لا تحتاج إلى أي مواصفات معقدة—فقط استخدم اسم الوحدة مباشرة. على سبيل المثال، إذا كان module_a.py و module_b.py في نفس الدليل، يمكنك استيرادهما كما يلي.
import module_a
لاستيراد دالة أو فئة محددة، يمكنك فعل ذلك بهذه الطريقة:
from module_a import some_function
الاستيراد من دليل أب
عند استيراد وحدة موجودة في دليل أب، استخدم .. للانتقال مستوىً واحدًا أعلى قبل تحديد الوحدة. على سبيل المثال، للاستيراد من مستوى واحد أعلى، يمكنك كتابة:
from ..module_a import some_function
الاستيراد من دليل فرعي
عند استيراد وحدة من دليل فرعي، حدد اسم الدليل واسم الوحدة مفصولين بنقطة. على سبيل المثال، يمكنك استيراد وحدة من دليل فرعي كما يلي.
from sub_package.module_b import some_function
يوفر استخدام المسارات النسبية ميزة رئيسية وهي بقاء الشيفرة مرنة حتى إذا تغير هيكل دليل المشروع.
٤. استيراد الوحدات داخل حزمة
لدى بايثون مفهوم “الحزمة” لتنظيم الوحدات. تُعد الحزم مفيدة لتجميع عدة وحدات معًا، خاصةً في المشاريع الكبيرة. يمكنك أيضًا استيراد الوحدات داخل حزمة باستخدام المسارات النسبية.
بنية الحزمة وملف __init__.py
عند إنشاء حزمة، تحتاج إلى إضافة ملف __init__.py إلى دليلها. هذا الملف يخبر بايثون بالتعرف على الدليل كحزمة. أدناه، سنشرح ذلك باستخدام مشروع له البنية التالية.
project/
├── main.py
├── package/
│ ├── __init__.py
│ ├── module_a.py
│ └── sub_package/
│ ├── __init__.py
│ └── module_b.py
استيراد المسار النسبي للوحدات داخل الحزمة
على سبيل المثال، لاستيراد module_a.py من module_b.py باستخدام مسار نسبي، يمكنك كتابة:
from ..module_a import some_function
هذا .. يعني الانتقال مستوى واحد إلى أعلى من الدليل الحالي. بهذه الطريقة، يمكنك مشاركة الدوال والفئات بين الوحدات داخل الحزمة.
أيضًا، عند استيراد وحدة من نفس الحزمة باستخدام مسار نسبي، يمكنك تحديدها بسهولة بنقطة.
from .module_a import some_function
هذا يسمح للوحدات في المشروع بالتفاعل بشكل مختصر، ولن تحتاج إلى تغييرات كبرى في الشيفرة حتى إذا تغيرت بنية الدليل.
5. الأخطاء الشائعة وحلولها
يمكن لاستيرادات بايثون بالمسار النسبي أن تنتج عدة أخطاء نمطية. يشرح هذا القسم هذه الأخطاء وكيفية حلها.
ImportError: attempted relative import with no known parent package
هذا الخطأ شائع يحدث عند محاولة استيراد وحدة باستخدام مسار نسبي، خاصةً عندما يتم تشغيل السكربت مباشرة. على سبيل المثال، قد يتسبب الكود التالي في المشكلة.
from ..module_a import some_function
يحدث هذا الخطأ لأن بايثون لا يستطيع التعرف على الحزمة الأم للسكربت. في بايثون، يجب أن تُعترف الوحدة بوضوح كجزء من حزمة. عندما يُشغل السكربت مباشرة، من المحتمل أن يتسبب استخدام المسار النسبي في حدوث خطأ.
الحل
إحدى الطرق لتجنب هذه المشكلة هي استخدام sys.path لتحديد مسار البحث عن الوحدات صراحة. على سبيل المثال، يمكنك إضافة الدليل الأب إلى مسار البحث باستخدام sys.path.append() كما يلي.
import sys
sys.path.append('..')
from module_a import some_function
هذا يسمح لبايثون بتحديد موقع الوحدة بشكل صحيح.
ModuleNotFoundError
خطأ شائع آخر هو ModuleNotFoundError. يحدث هذا عندما لا يمكن العثور على الوحدة المحددة. عند محاولة استيراد وحدة عبر مسار نسبي، قد يكون السبب أن موقع الوحدة غير صحيح أو أن sys.path لم يُضبط بشكل صحيح.
الحل
لحل هذه المشكلة، راجع عبارات الاستيراد وتأكد من أن الوحدة موجودة فعليًا. أيضًا، باستخدام sys.path.append() لتحديد الأدلة التي يمكن لبايثون العثور فيها على الوحدة صراحةً، يمكنك تجنب الخطأ.

6. أمثلة عملية وتطبيقات
نقدم هنا أمثلة شفرة ملموسة باستخدام استيرادات المسار النسبي. يوضح ذلك كيف يمكنك الاستفادة من المسارات النسبية في المشاريع الحقيقية.
مثال: الاستيراد من دليل أب
افترض بنية مشروع كما يلي.
project/
├── main.py
├── package/
│ ├── module_a.py
│ └── sub_package/
│ └── module_b.py
الشفرة التي تستورد الدالة some_function من module_b.py إلى module_a.py موضحة أدناه.
# module_b.py
from ..module_a import some_function
def use_function():
some_function()
في هذه الشفرة، يُستخدم .. للانتقال مستوى واحد إلى أعلى، وتُستورد الدالة من module_a. هذا النهج مفيد عند مشاركة الدوال أو الفئات عبر وحدات تمتد عبر أدلة متعددة.
مثال: استيراد الوحدات باستخدام sys.path
بعد ذلك، نعرض مثالًا لاستيراد وحدة من دليل أب باستخدام sys.path.append().
# module_b.py
import sys
sys.path.append('..')
from module_a import some_function
def use_function():
some_function()
في هذه الطريقة، يضيف sys.path الدليل الأب، مما يسمح لبايثون بتحديد موقع module_a بشكل صحيح. هذا النهج فعال بشكل خاص عند تشغيل السكربتات مباشرة.
7. الخاتمة
في هذه المقالة، قدمنا نظرة متعمقة على الاستيرادات ذات المسار النسبي في عبارات import في بايثون. الاستيرادات ذات المسار النسبي مفيدة بشكل خاص للمشاريع الكبيرة وتطوير الحزم لأنها تتيح لك إدارة الاعتمادات بين الوحدات بمرونة. ومع ذلك، يمكن أن تكون عرضة للأخطاء، لذا فإن التكوين السليم واستخدام sys.path أمران مهمان.
فهم فوائد الاستيرادات ذات المسار النسبي وتطبيقها في المشاريع الحقيقية يتيح إدارة أكثر كفاءة للكود.




