python - पाइथन में परिपत्र आयात निर्भरता




dependencies circular-dependency (4)

आप आयात को स्थगित कर सकते हैं, उदाहरण के लिए a/__init__.py :

def my_function():
    from a.b.c import Blah
    return Blah()

यानी, आयात को तब तक रोक दें जब तक कि इसकी वास्तव में आवश्यकता न हो। हालांकि, मैं अपने पैकेज परिभाषाओं / उपयोगों पर भी नजदीकी नजर रखूंगा, क्योंकि चक्रीय निर्भरता के रूप में एक दिशा-निर्देश एक डिजाइन समस्या का संकेत दे सकता है।

मान लें कि मेरे पास निम्न निर्देशिका संरचना है:

a\
    __init__.py
    b\
        __init__.py
        c\
            __init__.py
            c_file.py
        d\
            __init__.py
            d_file.py

पैकेज के __init__.py , c पैकेज आयात किया जाता है। लेकिन c_file.py आयात abd

प्रोग्राम विफल रहता है, कह रहा है कि b मौजूद नहीं है जब c_file.py abd आयात करने का प्रयास करता है। (और यह वास्तव में अस्तित्व में नहीं है, क्योंकि हम इसे आयात करने के बीच में थे।)

इस समस्या का समाधान कैसे किया जा सकता है?


एक और समाधान d_file के लिए प्रॉक्सी का उपयोग करना है।

उदाहरण के लिए, मान लीजिए कि आप blah क्लास को c_file से साझा करना चाहते हैं। इस प्रकार d_file में शामिल हैं:

class blah:
    def __init__(self):
        print("blah")

यहां आप c_file.py में दर्ज करते हैं:

# do not import the d_file ! 
# instead, use a place holder for the proxy of d_file
# it will be set by a's __init__.py after imports are done
d_file = None 

def c_blah(): # a function that calls d_file's blah
    d_file.blah()

और एक init में .py:

from b.c import c_file
from b.d import d_file

class Proxy(object): # module proxy
    pass
d_file_proxy = Proxy()
# now you need to explicitly list the class(es) exposed by d_file
d_file_proxy.blah = d_file.blah 
# finally, share the proxy with c_file
c_file.d_file = d_file_proxy

# c_file is now able to call d_file.blah
c_file.c_blah() 

यदि सी और सी पर निर्भर करता है, तो क्या वे वास्तव में एक ही इकाई नहीं हैं?

आपको वास्तव में जांच करनी चाहिए कि आपने दो पैकेजों में क्यों विभाजित किया है, क्योंकि आपके पास कुछ कोड है, आपको दूसरे पैकेज में विभाजित करना चाहिए (उन्हें दोनों नए पैकेज पर निर्भर करने के लिए, लेकिन एक-दूसरे को नहीं), या आपको उन्हें मर्ज करना चाहिए एक पैकेज में


समस्या यह है कि किसी निर्देशिका से चलते समय, डिफ़ॉल्ट रूप से केवल उप-निर्देशिका वाले संकुल उम्मीदवार आयात के रूप में दिखाई देते हैं, इसलिए आप abd आयात नहीं कर सकते हैं, हालांकि बी बी आयात कर सकते हैं क्योंकि बी बी का उप-पैकेज है।

यदि आप वास्तव में c/__init__.py में abd आयात करना चाहते हैं तो आप सिस्टम पथ को ऊपर से एक निर्देशिका के रूप में a/__init__.py और आयात एबीसी आयात करने के लिए a/__init__.py में आयात को बदलकर इसे पूरा कर सकते हैं

आपका a/__init__.py इस तरह दिखना चाहिए:

import sys
import os
# set sytem path to be directory above so that a can be a 
# package namespace
DIRECTORY_SCRIPT = os.path.dirname(os.path.realpath(__file__)) 
sys.path.insert(0,DIRECTORY_SCRIPT+"/..")
import a.b.c

जब आप स्क्रिप्ट के रूप में सी में मॉड्यूल चलाने के लिए चाहते हैं तो एक अतिरिक्त कठिनाई उत्पन्न होती है। यहां पैकेज ए और बी मौजूद नहीं हैं। आप sys.path को शीर्ष-स्तरीय निर्देशिका में इंगित करने के लिए c निर्देशिका में __int__.py को हैक कर सकते हैं और उसके बाद abd आयात करने के लिए पूर्ण पथ का उपयोग करने में सक्षम होने के लिए c के अंदर किसी भी मॉड्यूल में __init__ आयात करते हैं, मुझे शक है कि यह अच्छा अभ्यास है __init__.py आयात करने के लिए, लेकिन यह मेरे उपयोग के मामलों के लिए काम किया है।





python-import