يتم استيراد Python النسبي ضمن حزمة وليس على المسار

StackOverflow https://stackoverflow.com/questions/9011545

  •  14-11-2019
  •  | 
  •  

سؤال

كيف يمكنني استيراد ملف موجود في الدليل الأصلي ضمن حزمة بايثون (غير موجود في المسار) إلى ملف في دليل فرعي؟

لست واضحًا تمامًا فيما يتعلق بمفردات تغليف بايثون، على سبيل المثال:

dir1/
    __init__.py
    runner.py
    in_dir1.py
    dir2/
        __init__.py
        in_dir2.py

دير1/in_dir1.py:

def example():
    print "Hello from dir1/in_dir1.example()"

dir1/dir2/in_dir2.py

import in_dir1   #or whatever this should be to make this work
print "Inside in_dir2.py, calling in_dir1.example()"
print in_dir1.example()

بشرط dir1 ليس على مسار بايثون وأنا أبحث عن أفضل طريقة للاستيراد in_dir1 داخل in_dir2.

حاولت from .. import in_dir1 و from ..dir1 import in_dir1 بناءً على هذا السؤال/الجواب ولكن لا يعمل.ما هي الطريقة الصحيحة لتنفيذ تلك النية؟ هذا السؤال/أ يبدو أنه يحتوي على الجواب؛ومع ذلك، لست متأكدًا تمامًا مما سأفعله/كيفية حل مشكلتي باستخدام بيب 366

كلاهما __init__.py الملفات فارغة وأنا على v2.6.

أحاول القيام بذلك دون استخدام أي من طرق الاختراق التي يستمر Google في الكشف عنها.

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

المحلول

الجواب في الرابط الذي وضعته:

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

لا يمكنك إجراء عمليات استيراد نسبية في __main__ البرامج النصية (أي.إذا قمت بتشغيل مباشرة python in_dir2.py).

لحل هذه المشكلة، ما يسمح لك PEP 366 بفعله هو تعيين النطاق global __package__:

import dir1
if __name__ == '__main__':
    __package__ = 'dir1.dir2'
    from .. import in_dir1

لاحظ أن الحزمة dir1 لا يزال يتعين عليه أن يكون قيد التشغيل sys.path!يمكنك التلاعب sys.path لتحقيق هذا.ولكن بحلول ذلك الوقت، ما الذي حققته مقارنة بالواردات المطلقة؟

نصائح أخرى

أنت يستطيع في الواقع افعل هذا:

import sys
sys.path.append('..')

وهذا سوف ينجح.لكن لا تفعل ذلك.يمكن أن يكسر وحدات أخرى.

أعتقد أنه يمكنك إزالته مباشرة بعد الاستيراد، لكن لا تفعل ذلك.

يحرر:

في الواقع، هذا يعمل أيضًا وأعتقد أنه لا يوجد سبب لعدم أمانه:

داخل in_dir2.py يمكنك القيام بما يلي:

import sys
import os
current_module = sys.modules[__name__]
indir2file=current_module.__file__
sys.path.append(os.path.dirname(os.path.abspath(indir2file))+os.sep+".."+os.sep)
import in_dir1

حاول جاهدًا إعادة هيكلة التعليمات البرمجية الخاصة بك بدلاً من ذلك.

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