अजगर मॉड्यूल के पूर्ण बनाम स्पष्ट सापेक्ष आयात


85

मैं पायथन एप्लिकेशन में पैकेज आयात करने के पसंदीदा तरीके के बारे में सोच रहा हूं। मेरे पास इस तरह एक पैकेज संरचना है:

project.app1.models
project.app1.views
project.app2.models

project.app1.viewsआयात project.app1.modelsऔर project.app2.models। ऐसा करने के दो तरीके हैं जो दिमाग में आते हैं।

पूर्ण आयात के साथ:

import A.A
import A.B.B

या स्पष्ट सापेक्ष आयात के साथ, जैसा कि PEP 328 के साथ Python 2.5 में पेश किया गया है :

# explicit relative
from .. import A
from . import B

ऐसा करने का सबसे पाइथोनिक तरीका क्या है?


"स्पष्ट सापेक्ष" उदाहरण वाक्यविन्यास त्रुटियां हैं। रिश्तेदार आयात के रूप में होना चाहिए from _ import ..., इसलिए आपके उदाहरण होंगे from .. import Aऔरfrom . import B
MestreLion

@MestreLion अच्छा पकड़, आप बिल्कुल सही हैं! मैंने से अपना प्रश्न अपडेट import ..Aकिया from .. import A। उल्लेखनीय है कि किसी को
नजर आने

जवाबों:


52

पूर्ण आयात। PEP 8 से:

इंट्रा-पैकेज आयात के लिए सापेक्ष आयात अत्यधिक हतोत्साहित होते हैं। सभी आयातों के लिए हमेशा पूर्ण पैकेज पथ का उपयोग करें। यहां तक ​​कि अब जब PEP 328 [7] Python 2.5 में पूरी तरह से लागू हो गया है, तो इसकी स्पष्ट सापेक्ष आयात की शैली सक्रिय रूप से हतोत्साहित होती है; पूर्ण आयात अधिक पोर्टेबल हैं और आमतौर पर अधिक पठनीय हैं।

स्पष्ट सापेक्ष आयात एक अच्छी भाषा सुविधा है (मुझे लगता है), लेकिन वे लगभग पूर्ण आयात के रूप में स्पष्ट नहीं हैं। अधिक पठनीय रूप है:

import A.A
import A.B.B

खासकर यदि आप कई अलग-अलग नामस्थानों का आयात करते हैं। यदि आप कुछ अच्छी तरह से लिखे गए प्रोजेक्ट्स / ट्यूटोरियल्स को देखते हैं, जिसमें पैकेजों के भीतर आयात शामिल हैं, तो वे आमतौर पर इस शैली का अनुसरण करते हैं।

आपके द्वारा अधिक स्पष्ट किए जाने वाले कुछ अतिरिक्त कीस्ट्रोक्स दूसरों को (और शायद आपको) भविष्य में बहुत समय बचाएंगे जब वे आपके नाम स्थान का पता लगाने की कोशिश कर रहे हों (खासकर यदि आप 3.x पर जाते हैं, जिसमें कुछ पैकेज हैं) नाम बदल गए हैं)।


@ सुरक्षित, "कुछ अच्छी तरह से लिखा परियोजनाओं को देखो ..." किसी भी सुझाव?
डेनिस

@ डेनिस: रिटवेल्ड गुइडो वैन रोसुम का अपना प्रोजेक्ट है, इसलिए मैं सोचूंगा कि यह देखने के लिए एक अच्छी जगह होगी ( code.google.com/p/rietveld )। पायथन मानक पुस्तकालय इतना महान नहीं है, उस कोड का एक बहुत सम्मेलनों का पालन नहीं करता है।
राफे केटलर

68
@ रीफ: PEP-8 का वह हिस्सा पुराना है, जो गुइडो के अनुसार पुराना है। mail.python.org/pipermail/python-dev/2010-ctober/104476.html
ब्रैंडन रोड्स

12
यह कथन अब PEP-8 में बिल्कुल भी नहीं है। अब यह बताता है कि पूर्ण आयात की सिफारिश की जाती है, लेकिन सापेक्ष आयात एक स्वीकार्य विकल्प है।
डैनो

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

122

पायथन रिश्तेदार आयात अब दृढ़ता से हतोत्साहित नहीं होते हैं, लेकिन निरपेक्षता का उपयोग करते हुए उस मामले में दृढ़ता से सुझाव दिया जाता है।

कृपया इस चर्चा को स्वयं Guido का हवाला देते हुए देखें :

"क्या यह ज्यादातर ऐतिहासिक नहीं है? जब तक कि नए रिश्तेदार-आयात सिंटैक्स को लागू नहीं किया गया था, रिश्तेदार आयातों के साथ विभिन्न समस्याएं थीं। अल्पकालिक समाधान का उपयोग करने की अनुशंसा नहीं करना था। दीर्घकालिक समाधान एक अस्पष्ट सिंटैक्स को लागू करना था। अब यह एंटी-सिफारिश को वापस लेने का समय है। बेशक, ओवरबोर्ड के बिना - मैं अभी भी उन्हें एक अधिग्रहीत स्वाद पाता हूं, लेकिन उनके पास कोई स्थान नहीं है। "

ओपी पीईपी 328 को सही ढंग से जोड़ता है जो कहता है:

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

पाइथन में रिश्तेदार आयात का उपयोग कब या क्यों करना है, यह भी लगभग डुप्लिकेट प्रश्न देखें

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

PEP 328 उपयोग से नए व्यवहार के लिए मजबूर करने के लिए:

from __future__ import absolute_import

इस मामले में, निहित सापेक्ष आयात अब संभव import localfileनहीं होगा (जैसे अब केवल काम नहीं करेगा from . import localfile)। स्वच्छ और भविष्य के प्रमाण व्यवहार के लिए, निरपेक्ष_समूह का उपयोग करना उचित है।

एक महत्वपूर्ण चेतावनी यह है कि PEP 338 और PEP 366 के कारण , सापेक्ष आयातों के लिए अजगर को मॉड्यूल के रूप में आयात करने की आवश्यकता होती है - आप किसी ऐसे फ़ाइलहोम को निष्पादित नहीं कर सकते हैं जिसका कोई रिश्तेदार आयात करता है या आपको एक मिलेगा ValueError: Attempted relative import in non-package

सर्वोत्तम दृष्टिकोण का मूल्यांकन करते समय इस सीमा को ध्यान में रखा जाना चाहिए। गुइडो किसी भी मामले में एक मॉड्यूल से स्क्रिप्ट चलाने के खिलाफ है:

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

मामले पर व्यापक चर्चा एसओ पर पाई जा सकती है; कर रहे हैं। अजगर 3 यह काफी व्यापक है:


9
गुइडो ने लिखा कि 2010 में और यह अभी भी पीईपी में है? यदि वे इतने पुराने हैं तो हम पीईपी पर कैसे भरोसा कर सकते हैं?
जबा

2
पीईपी इस मायने में अमेरिकी संशोधन की तरह है कि आप चीजों में संशोधन कर सकते हैं। अस्वीकृत पीईपीएस भी बहुत हैं। पीईपी प्रस्ताव हैं। उन्हें स्वीकार, अस्वीकार या अप्रचलित हो सकता है जिसका अर्थ अक्सर नए पीईपी होता है। PEP 8 एक स्टाइल गाइड है, इसलिए इसे जगह में संशोधित किया जा सकता है।
कैप्लनियर

2
मैं "पैकेज के अंदर एक मॉड्यूल आसानी से खुद को आयात नहीं कर सकता ..." भाग के बारे में उलझन में हूं। मैंने पहले कभी खुद को आयात करने वाले मॉड्यूल के बारे में नहीं सुना था।
मटियासेलसको

2
एक संभावित उदाहरण @matiascelasco: यदि आपके पास foo / bar.py और foo / baz.py है, लेकिन baz.py भी। यदि आप बार से foo.baz आयात करना चाहते हैं, तो आप यह सुनिश्चित करना चाहते हैं कि आप क्या आयात कर रहे हैं, जैसे। import .bazहालांकि यह पीईपी में वर्णित कई समान स्थितियों का सिर्फ एक सरलीकरण है।
स्टेफानो

आपका उत्तर स्पष्ट रूप से उन्हें अनुमति देने में परिवर्तन को स्पष्ट नहीं करता है। निहित सापेक्ष आयातों का उपयोग कभी नहीं किया जाना चाहिए, लेकिन स्पष्ट सापेक्ष आयातों का उपयोग करना ठीक है। Python3 से अवैध रिश्तेदार को हटा दिया गया है।
उन्नीस

33

रिश्तेदार आयात न केवल दर्जनों आंतरिक आयातों को बदलने के बिना, आपको बाद में अपने पैकेज का नाम बदलने के लिए स्वतंत्र छोड़ देते हैं, लेकिन मुझे उनके साथ परिपत्र आयात या नाम स्थान पैकेज जैसी चीजों को हल करने में भी सफलता मिली है, क्योंकि वे पायथन को वापस नहीं भेजते हैं। शीर्ष "शीर्ष-स्तरीय नाम स्थान से फिर से अगले मॉड्यूल के लिए खोज शुरू करने के लिए।"


4
यह पायथन स्टाइल गाइड के अनुसार हतोत्साहित शैली है। वे गंभीर रूप से पठनीयता को बादल देते हैं और कथित "सुविधा" के लायक नहीं होते हैं, जिसके लिए आप उससे सहमत हैं। यदि आपको किसी समस्या को हल करने के लिए रिश्तेदार आयात का उपयोग करने की आवश्यकता है, तो आप इसे गलत कर रहे हैं।
राफे केटलर

14
अन्य उत्तर पर उसकी (ब्रैंडन रोड्स) टिप्पणी पर ध्यान दें, जिसमें एक लिंक दिखाया गया है कि यह अब हतोत्साहित नहीं है।
जॉन कूम्ब्स

1
@RafeKettler क्या आप बता सकते हैं कि आप एक ऐसे पैकेज में पूर्ण आयात का उपयोग कैसे करेंगे जो स्वयं दूसरे पैकेज में शामिल है? पूर्ण आयात आंतरिक पैकेज में विफल हो जाएगा क्योंकि वे नए शीर्ष स्तर के बारे में नहीं जानते हैं। रिश्तेदार आयात करना जारी रखते हैं। एक शायद यह तर्क दे सकता है कि पैकेज को पहली जगह में दूसरे के अंदर नहीं होना चाहिए, लेकिन कुछ कोड को पुन: उपयोग करने योग्य माना जाता है और यह बहुत कुछ होता है। बहुत से पुन: उपयोग किए गए कोड को जनता के लिए पैक नहीं किया जाता है और इसलिए एक अलग पैकेज के रूप में प्रदान नहीं किया जाता है इसलिए VCS आयात /
सबमॉड्यूल्स

3
@meowsqueak मैं सहमत हूं, कुछ पैकेज आसानी से इंस्टॉल करने योग्य नहीं होते हैं (वे पाइप पर नहीं होते हैं, आप उपयोग नहीं करना चाहते हैं python setup.py installया python setup.py developजो भी कारण हो), उन मामलों में मैं स्रोत कोड को फोर्क करता हूं और इसे गिट सबमॉड्यूल के रूप में जोड़ता हूं। जब वे पैकेज अपने स्वयं के पैकेज के नाम पर पूर्ण आयात का उपयोग करते हैं, तो उनका आयात विफल हो जाता है। एकमात्र समाधान स्पष्ट सापेक्ष आयात का उपयोग करना है। मुझे लगता है कि प्रोत्साहित किया जाना चाहिए कि क्या है
CMCDragonkai
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.