2010-11-17 5 views
57

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

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

project.app1.views आयात project.app1.models और project.app2.models: मैं इस तरह एक पैकेज संरचना है। ऐसा करने के दो तरीके हैं जो दिमाग में आते हैं। Python 2.5 with PEP 328 में

import A.A 
import A.B.B 

या स्पष्ट रिश्तेदार आयात के साथ शुरू के रूप में:

# explicit relative 
import ..A 
import .B 

ऐसा करने का सबसे pythonic तरीका क्या है

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

?

उत्तर

28

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

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

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

import A.A 
import A.B.B 

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

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

+1

हाँ, यह वहाँ पिछली बार मैं पीईपी 8 के माध्यम से पढ़ा नहीं था! –

+0

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

+0

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

27

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

+1

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

+7

, नोट उसकी (ब्रैंडन रोड्स) अन्य जवाब पर टिप्पणी दिखा रहा है कि यह अब हतोत्साहित है एक लिंक के साथ। –

+0

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

89

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

"यह ज्यादातर ऐतिहासिक नहीं है नई रिश्तेदार आयात वाक्य रचना लागू किया गया था वहाँ रिश्तेदार आयात के साथ विभिन्न समस्याओं थे अल्पकालिक समाधान था जब तक:।

कृपया this discussion का हवाला देते हुए गुइडो खुद को देखने के । उनका उपयोग न सिफारिश करने के लिए लंबी अवधि के समाधान एक स्पष्ट वाक्य रचना को लागू करने के लिए था अब यह के लिए समय अनुशंसा-रोधी वापस लेने है बेशक, पानी में गिर जा रहा बिना - मैं अभी भी उन्हें एक अधिग्रहीत स्वाद प्राप्त होता है;।। लेकिन वे उनकी जगह है"

ओपी सही ढंग से लिंक PEP 328 कि कहते हैं:

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

भी देख सकते हैं लगभग डुप्लिकेट प्रश्न When or why to use relative imports in Python

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

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

from __future__ import absolute_import 

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

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

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

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

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

+8

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

+1

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

+2

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

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

  • कोई संबंधित समस्या नहीं^_^