पायथन में रिश्तेदार आयात के साथ क्या गलत है?


89

मैंने हाल ही में एक लोकप्रिय पायथन शैली-चेकर के पाइलिंट के उन्नत संस्करण बनाए हैं

यह मेरे पूरे कोड में बैलिस्टिक हो गया है, उन जगहों की ओर इशारा करता है जहां मैं पूर्ण पैकेज पथ निर्दिष्ट किए बिना एक ही पैकेज में मॉड्यूल आयात करता हूं।

नई त्रुटि संदेश W0403 है।

W0403: सापेक्ष आयात% r,% r होना चाहिए

पैकेज निर्देशिका के सापेक्ष आयात का पता चलने पर उपयोग किया जाता है।


उदाहरण

उदाहरण के लिए, यदि मेरे पैकेज इस तरह संरचित हैं:

/cake
  /__init__.py
  /icing.py
  /sponge.py
/drink

और स्पंज पैकेज में मैं लिखता हूं:

import icing

के बजाय

import cake.icing

मुझे यह त्रुटि मिलेगी।


जबकि मैं समझता हूं कि सभी पाइलिंट संदेश समान महत्व के नहीं हैं, और मैं उन्हें खारिज करने से डरता नहीं हूं, मुझे समझ नहीं आता कि इस तरह के अभ्यास को एक खराब विचार क्यों माना जाता है।

मैं उम्मीद कर रहा था कि कोई व्यक्ति नुकसान के बारे में बता सकता है, इसलिए मैं अपनी कोडिंग शैली में सुधार कर सकता हूं (जैसा कि मैं वर्तमान में करने की योजना बना रहा हूं) इस जाहिरा तौर पर चेतावनी को बंद करना।

जवाबों:


97

समस्या import icingयह है कि आपको पता नहीं है कि इसका पूर्ण आयात या रिश्तेदार आयात है या नहीं। icingअजगर के मार्ग में एक मॉड्यूल, या वर्तमान मॉड्यूल में एक पैकेज हो सकता है। यह काफी कष्टप्रद है जब एक स्थानीय पैकेज में अजगर मानक पुस्तकालय पैकेज के समान नाम होता है।

आप कर सकते हैं from __future__ import absolute_importजो पूरी तरह से निहित सापेक्ष आयात को बंद कर देता है। यह PEP 328 में अस्पष्टता के बारे में इस औचित्य सहित वर्णित है । मेरा मानना ​​है कि पायथन 3000 का अनुमान है कि रिश्तेदार आयात पूरी तरह से बंद हो गए हैं।

आप अभी भी रिश्तेदार आयात कर सकते हैं, लेकिन आपको उन्हें स्पष्ट रूप से करना होगा, जैसे:

from . import icing

2
+1 विशेष रूप से समझौता समाधान के लिए, जो कि शायद मुझे जाना चाहिए।
विषम

2
नोट आप import .icingइसके बजायfrom . import icing
जैक

11
@ जैक वास्तव में मुझे नहीं लगता कि आप कर सकते हैं। से PEP328 के इस हिस्से : सापेक्ष आयात हमेशा का उपयोग करना चाहिए from <> import; import <>हमेशा निरपेक्ष है। बेशक, पूर्ण आयात from <> importअग्रणी डॉट्स को छोड़ कर उपयोग कर सकते हैं । कारण import .fooनिषिद्ध है क्योंकि import XXX.YYY.ZZZतब XXX.YYY.ZZZएक अभिव्यक्ति में प्रयोग करने योग्य है। लेकिन .moduleYएक अभिव्यक्ति में प्रयोग करने योग्य नहीं है।
एक

48

कुछ अच्छे कारण हैं:

  1. जब आप किसी मॉड्यूल को इधर-उधर करते हैं, तो सापेक्ष आयात आसानी से टूट जाता है।

    कल्पना कीजिए कि आपके पैकेज में एक foo.barfoo.bazऔर एक bazमॉड्यूल है। foo.barआयात foo.baz, लेकिन एक रिश्तेदार आयात का उपयोग कर।

    अब, यदि आप आगे बढ़ना foo.barचाहते हैं bar, तो आपका मॉड्यूल अचानक एक अलग आयात कर रहा है baz!

  2. सापेक्ष आयात अस्पष्ट हैं। यहां तक ​​कि barउपरोक्त उदाहरण में मॉड्यूल के चारों ओर घूमने के बिना , आपकी परियोजना में आने वाले एक नए डेवलपर को यह एहसास नहीं होने के लिए माफ किया जा सकता है कि bazवास्तव foo.bazमें रूट-स्तरीय bazपैकेज के बजाय है ।

    निरपेक्ष आयात यह स्पष्ट करता है कि किस मॉड्यूल का उपयोग किया जा रहा है। और import thisउपदेश के रूप में , स्पष्ट निहितार्थ से बेहतर है।

  3. पायथन 3 ने पूरी तरह से अंतर्निहित आयात को अक्षम कर दिया है; आयात को अब हमेशा निरपेक्ष माना जाता है, जिसका अर्थ है कि उपरोक्त उदाहरण import bazमें हमेशा शीर्ष-स्तरीय मॉड्यूल आयात होगा। आपको इसके बजाय स्पष्ट आयात सिंटैक्स का उपयोग करना होगा ( from . import baz)।

    पायथन 2 से 3 का उदाहरण पेश करने से इस प्रकार अप्रत्याशित समस्याएं पैदा होंगी, अब पूर्ण आयात का उपयोग करने से आपका कोड भविष्य में प्रूफ हो जाएगा।


10
# 2 और # 3 के लिए +1। लेकिन # 1 को पूरे निर्देशिका में स्थानांतरित करने पर क्या होता है (जैसे एक स्तर नीचे धकेल दिया जाता है) के विरुद्ध ऑफसेट होना चाहिए।
विषम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.