2015-11-13 12 views
6

पायथन बेहद सुरुचिपूर्ण भाषा है। खैर, छोड़कर ... आयात को छोड़कर। मैं अभी भी इसे मेरे लिए प्राकृतिक लगने के तरीके से काम नहीं कर सकता।सर्कुलर आयात नरक

मेरे पास कक्षा MyObjectA है जो फ़ाइल mypackage/myobjecta.py में है। यह ऑब्जेक्ट कुछ उपयोगिता फ़ंक्शंस का उपयोग करता है जो mypackage/utils.py में हैं। तो myobjecta.py में मेरी पहली लाइनों में मैं लिखने:

from mypackage.utils import util_func1, util_func2 

लेकिन उपयोगिता कार्यों में से कुछ बना सकते हैं और नए उदाहरणों लौट MyObjectA की। तो मुझे utils.py में लिखना होगा:

from mypackage.myobjecta import MyObjectA 

ठीक है, नहीं, मैं नहीं कर सकता। यह एक गोलाकार आयात है और पायथन ऐसा करने से इंकार कर देगा।

इस मुद्दे के बारे में यहां कई सवाल हैं, लेकिन कोई भी संतोषजनक उत्तर नहीं दे रहा है। जो मैं सभी उत्तरों में पढ़ सकता हूं उससे:

  1. अपने मॉड्यूल को पुनर्गठित करें, आप इसे गलत कर रहे हैं! लेकिन मुझे पता नहीं है कि मेरे मॉड्यूल को इतनी सरल स्थिति में व्यवस्थित करना कितना बेहतर है क्योंकि प्रस्तुत किया गया है।
  2. सिर्फ import ... बल्कि from ... import ... से (व्यक्तिगत रूप से मैं लिख सकते हैं और संभवतः सभी पूर्ण नाम क्वालिफायर refactor करने के लिए नफरत है, मैं वास्तव में क्या मैं बाहर की दुनिया से मॉड्यूल में आयात कर रहा हूँ देखने के लिए प्यार करता हूँ) की कोशिश करो। क्या इससे मदद मिलेगी? मुझे यकीन नहीं है, अभी भी परिपत्र आयात हैं।
  3. हैक करें जैसे कि अन्य मॉड्यूल से कुछ उपयोग करने से पहले एक फ़ंक्शन बॉडी के आंतरिक दायरे में कुछ आयात करें।

मुझे अभी भी उम्मीद है कि समाधान संख्या 4 है) जो कार्यात्मक और सुरुचिपूर्ण और सरल और काम करने के अर्थ में पाइथोनिक होगा। या नहीं है?

नोट: मैं मुख्य रूप से एक सी ++ प्रोग्रामर हूं, ऊपर दिया गया उदाहरण इसी तरह के हेडर सहित आसानी से सुलझाया गया है कि मुझे विश्वास नहीं है कि यह पायथन में संभव नहीं है।

def some_function(): 
    import logging 
    do_some_logging() 

आमतौर पर ImportError ही क्योंकि जिस तरह से import() के उठाए गए हैं पूरी फ़ाइल के शीर्ष स्तर स्टेटमेंट का मूल्यांकन करता है जब कहा जाता है:

+0

आप जो कहते हैं उससे, मैं या तो MyObjectA को utils.py में डाल दूंगा क्योंकि कुछ उपयोगिता फ़ंक्शन इसे वापस कर देते हैं, या मैं उपयोगिता फ़ंक्शन डालता हूं जो myobjecta.py में MyObjectA देता है। लेकिन इसका जवाब 1) – DainDwarf

+0

मैंने अजगर परिपत्र आयात की खोज की और कई प्रश्न पाए। क्या आपने खोज की –

+0

@ डेन: हाँ, निश्चित रूप से ऐसा कर सकता है अगर उपयोगिता फ़ंक्शन केवल MyObjectA लौटाते हैं। लेकिन क्या होगा यदि वे MyObjectB या MyObjectC आदि भी लौट सकें –

उत्तर

0

एक समारोह शरीर में कुछ आयात करने के बारे hackish कुछ भी नहीं है, यह एक पूरी तरह से वैध पैटर्न है ।

मामले में आप एक तर्क सर्कुलर निर्भरता ... की जरूरत नहीं है, कुछ भी नहीं अजगर में असंभव है ...

इसके चारों ओर एक तरीका नहीं है अगर आप सकारात्मक शीर्ष पर अपने आयात करना चाहते हैं:

:

डेविड Beazleys उत्कृष्ट बात Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00 से, यहां अजगर में परिपत्र आयात से निपटने के लिए एक रास्ता है

try: 
    from images.serializers import SimplifiedImageSerializer 
except ImportError: 
    import sys 
    SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer'] 

यह SimplifiedImageSerializer आयात करने का प्रयास करता है और यदि ImportError उठाया गया है, क्योंकि यह पहले ही आयात किया गया है, तो यह इसे आयातकैच से खींच देगा।

पुनश्च: आप दाऊद Beazley के आवाज में इस पूरे पोस्ट को पढ़ने के लिए।

+1

धन्यवाद, मैं निश्चित रूप से उस बात को देखने में समय लगेगा। फिर भी, अंदरूनी फ़ंक्शन आयात करना बहुत ही आसान समाधान है जो इसे 'बहुत पाइथोनिक' पदक के लिए अर्हता प्राप्त करने के लिए नहीं है। यह मॉड्यूल निर्भरता को छुपाता है और इसे कोड में भेज देता है। कोड में सभी आयात क्यों नहीं करते हैं? मुझे इसमें तर्क याद आती है ... लेकिन हाँ, यह ज्यादातर समय काम करता है। और पाइथन में आयात की आईएमएचओ) त्रुटिपूर्ण अवधारणा को रोकने के लिए प्रयास/पकड़ का उपयोग करना ... निश्चित रूप से एक हैक है। –

0

अपने मुख्य मॉड्यूल में mypackage.utils आयात न करें, यह पहले से ही mypackage.myobjecta में मौजूद है। एक बार जब आप mypackage.myobjecta आयात करते हैं तो उस मॉड्यूल से कोड निष्पादित किया जा रहा है और आपको अपने वर्तमान मॉड्यूल में कुछ भी आयात करने की आवश्यकता नहीं है, क्योंकि mypackage.myobjecta पहले से ही पूरा हो चुका है।

+0

क्या यह एक अच्छा समाधान है? अगर मैं 'मुख्य' मॉड्यूल से उपयोगिता कार्यों का उपयोग करना चाहता हूं तो क्या होगा। तब मैं 'utils 'को' main' में आयात न करके इस निर्भरता को अस्पष्ट कर दूंगा। 'Myobjecta.py' के दृष्टिकोण से,' utils.py' का उपयोग करके केवल एक कार्यान्वयन विवरण है। जब मैं बाद में इस कार्यान्वयन के विवरण को बदलने का फैसला करता हूं तो यह संभावित रिफैक्टरिंग अराजकता प्रस्तुत करता है ... और यह 'myobjecta.py' और 'utils.py' के बीच परिपत्र आयात को कैसे तोड़ता है? लेकिन शायद मैं इस मुद्दे को गलत समझा। –

+0

आप उन्हें इस तरह आयात कर सकते हैं: 'mypackage.myobjecta आयात ut_func1, util_func2' से पहले से वे उस पैकेज में पहले से ही – Nhor

+0

हैं लेकिन जैसा कि मैंने उल्लेख किया है,' myobjecta 'से 'utils' का उपयोग करके केवल एक कार्यान्वयन विवरण है। अगर मैं बाद में इसे बदलूं तो क्या होगा। तब मुझे एक ही समय में 'utils' और' myobjecta 'का उपयोग करने वाली हर चीज को फिर से लिखना होगा। मैं व्यक्तिगत रूप से इसे एक हैक मानता हूं क्योंकि यह उपयोगकर्ता को कार्यान्वयन विवरण जानने के लिए मजबूर करता है। यह एक अच्छा डिजाइन नहीं है। और बीटीडब्ल्यू। यह 'myobjecta' और' utils' के बीच परिपत्र आयात को तोड़ता नहीं है। या यह है? मुझे यह नहीं मिला। –

0

जिस तरह से मैं अपने (पहले) प्रोजेक्ट में इसके आसपास आया था, बस पूरे मॉड्यूल को दूसरे के शरीर में कॉपी और पेस्ट कर रहा था और केवल एक आयात का उपयोग करता था। कोड डुप्लिकेशन, सुरुचिपूर्ण, लेकिन यह मुझे आगे बढ़ने की अनुमति दी।

+0

मेरे पास समान समस्याएं हैं I मैं एक Ptyhon निर्यात नहीं है लेकिन यह भयानक लगता है। आपने अपनी (दूसरी) परियोजना में क्या किया? – smerlung

+0

यह फिर से कभी नहीं आया, शुक्र है, लेकिन जिस तरह से मैं इसे अब करूँगा वह एक और मॉड्यूल तैयार करेगा और इसमें दो अन्य आयात करेगा। – postoronnim

संबंधित मुद्दे