سؤال

لنفترض أن لدي بنية مجلد تبدو كما يلي:

.
├── A
│   ├── a.py
│   └── b.py
└── main.py

تحتوي الملفات على المحتوى التالي:

ب.py:

class BClass:
    pass

a.py:

from b import BClass

main.py:

from A import a

إذا ركضت python3.3 A/a.py أو python3.3 B/b.by, ، لا توجد أخطاء.ومع ذلك، إذا قمت بتشغيل python3.3 main.py, ، يحدث الخطأ التالي:

Traceback (most recent call last):
  File "main.py", line 1, in <module>
    from A import a
  File "/tmp/python_imports/A/a.py", line 1, in <module>
    from b import BClass
ImportError: No module named 'b'

تغيير سطر الاستيراد في a.py إلى import A.b يعمل، ولكن من الواضح python3.3 A/a.py سوف تفشل بعد ذلك.أنا لست مهتمًا فعليًا بالجري python3.3 A/a.py ولكني أريد أن تكون الوحدة قابلة للاستيراد من مواقع متعددة.لذلك يجب أن يقوم a.py باستيراد b.py بغض النظر عن مكان استيراد a.py.

كيف يمكن حل هذه المشكلة؟

هل كانت مفيدة؟

المحلول

إلى جانب ال __init__.py لقد ذكرت في تعليقي أنه إلزامي للحزم، فأنت بحاجة إلى استيراد الوحدة الشقيقة نسبيًا:

from .b import BClass

ثم يعمل أيضًا في Python 3.

وبدلاً من ذلك يمكنك بالطبع استيراد الاسم الكامل:

from A.b import BClass

ولكن بعد ذلك لا يمكن نقل الوحدة النمطية الخاصة بك بسهولة داخل شجرة الحزمة الخاصة بك.

بأي حال من الأحوال، على الرغم من أنك قادر على استخدام a.py كقائمة بذاتها.لتحقيق ذلك سوف تحتاج إلى إحاطة import بيان مع try/except وجرب إصدارًا مختلفًا في حالة فشل الإصدار الأول:

try:
  from .b import BClass
except ValueError:
  from b import BClass

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

نصائح أخرى

أنت بحاجة إلى __init__.py ملف (فارغ سيكون على ما يرام) في ملف A الدليل.وإلا فإن بايثون لن يتعرف عليها كحزمة.

الآن أنت عبارة عن حزمة، يجب عليك استخدام إما الواردات المطلقة أو الواردات النسبية الصريحة.في هذه الحالة، في A/a.py إما استخدام from A.b import BClass أو from .b import BClass.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top