पायथन में एक सापेक्ष पथ से आयात करना


104

मेरे पास मेरे क्लाइंट कोड के लिए एक फ़ोल्डर, मेरे सर्वर कोड के लिए एक फ़ोल्डर और कोड के लिए एक फ़ोल्डर है जो उनके बीच साझा किया गया है

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

मैं Server.py और Client.py से Common.py आयात कैसे करूँ?


जवाबों:


140

EDIT नवंबर 2014 (3 साल बाद):

पायथन 2.6 और 3.x उचित सापेक्ष आयात का समर्थन करता है, जहाँ आप कुछ भी करने से बच सकते हैं। इस पद्धति के साथ, आप जानते हैं कि आप एक पूर्ण आयात के बजाय एक सापेक्ष आयात प्राप्त कर रहे हैं । '..' का अर्थ है, मेरे ऊपर की निर्देशिका पर जाएं:

from ..Common import Common

एक चेतावनी के रूप में, यह केवल तभी काम करेगा जब आप पैकेज के बाहर से एक मॉड्यूल के रूप में अपने अजगर को चलाते हैं । उदाहरण के लिए:

python -m Proj

मूल हैकरी रास्ता

यह विधि अभी भी आमतौर पर कुछ स्थितियों में उपयोग की जाती है, जहां आप वास्तव में कभी अपने पैकेज को 'स्थापित' नहीं कर रहे हैं। उदाहरण के लिए, यह Django उपयोगकर्ताओं के साथ लोकप्रिय है।

आप अपने sys.path में कॉमन / जोड़ सकते हैं (चीजों को आयात करने के लिए पथ अजगर की सूची):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__) बस आपको वह निर्देशिका देता है जो आपकी वर्तमान अजगर फ़ाइल में है, और फिर हम 'सामान्य /' निर्देशिका पर नेविगेट करते हैं और मॉड्यूल को 'सामान्य' आयात करते हैं।


2
अजगर मॉड्यूल को मैन्युअल रूप से संशोधित न करें, केवल त्वरित हैक के लिए हो सकता है। डिस्टिल्स, सेटपूल आदि का उपयोग करके पायथन पैकेज प्रबंधन सीखना आमतौर पर एक आवश्यक कौशल है जो इस तरह की समस्याओं को हल करेगा।
साशा गॉटफ्रीड 19

1
@SaschaGottfried पूरी तरह से सहमत हैं, हालांकि यदि आप एक वितरण योग्य पैकेज नहीं बना रहे हैं, तो यह संभवत: कोई फर्क नहीं पड़ेगा। उदाहरण के लिए, Django में आप वास्तव में अपने ऐप को डिस्टिलिट्स के साथ स्थापित नहीं करते हैं, इसलिए उपरोक्त विधि एक आसान हैक है। लेकिन वैसे भी मैंने इन दिनों जो कुछ भी किया है, उसका उत्तर मैंने संपादित किया है।
डेव

32
उचित तकनीक के बारे में उपदेश देने के बजाय वास्तविक प्रश्न का उत्तर देने के लिए धन्यवाद। रिश्तेदार आयात करने के लिए बहुत सारे अच्छे कारण हैं।
shrewmouse

आप एक से अधिक स्तर पर कैसे जाएंगे?
19x पर jxramos

10
एक और स्तर ऊपर जाने के लिए, प्रत्येक स्तर के लिए एक अतिरिक्त बिंदु का उपयोग करें। @jxramos पूर्व: from ...myfileजाता है../../myfile
वाटसएबॉक्स

10

काफी मजेदार, एक ही समस्या जो मुझे मिली, और मुझे यह काम निम्नलिखित तरीके से मिला:

लिनक्स कमांड के साथ संयोजन ln, हम बात को बहुत अधिक कर सकते हैं:

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

और, अब यदि आप some_stuffफ़ाइल से आयात करना चाहते हैं : Proj/Common/Common.pyअपनी फ़ाइल में:, Proj/Client/Client.pyबस इस तरह:

# in Proj/Client/Client.py
from Common.Common import some_stuff

और, वही लागू होता है Proj/Server, setup.pyप्रक्रिया के लिए भी काम करता है, यहां एक ही प्रश्न पर चर्चा की जाती है , आशा है कि यह मदद करता है!


10

रिश्तेदार आयात मत करो।

से PEP8 :

इंट्रा-पैकेज आयात के लिए सापेक्ष आयात अत्यधिक हतोत्साहित किया जाता है।

अपने सभी कोड को एक सुपर पैकेज (यानी "myapp") में रखें और क्लाइंट, सर्वर और कॉमन कोड के लिए सबपेकेज का उपयोग करें।

अपडेट: " पायथन 2.6 और 3.x उचित सापेक्ष आयात (...) का समर्थन करता है ।" देखें डेव जवाब अधिक जानकारी के लिए।


1
कल्पना करें कि आप ' if __name__ == "__main__":' लाइन के बाद क्लाइंट और सर्वर के अंत में कुछ कोड जोड़ते हैं । यही है, आप उन्हें स्टैंड-अलोन स्क्रिप्ट के रूप में उपयोग करने में सक्षम होना चाहते हैं। इसे ठीक से कैसे करें? मुझे लगता है कि यह पूरी तरह से सामान्य उपयोग का मामला है जिसका समर्थन किया जाना चाहिए। इसे हतोत्साहित क्यों किया जाता है?
जबा

83
मुझे आश्चर्य है कि "डोन्ट डू इट" एक "मैं कैसे करूँ" के लिए स्वीकृत उत्तर है। प्रश्न (अच्छी तरह से, R <<g> को छोड़कर।) ऐसा करने के लिए कभी-कभार कारण होते हैं। मैं डेव सुझाव के समान एक समाधान का उपयोग करता हूं।
टॉम विल्सन

1
@TomWilson: यह शुद्ध नहीं है "यह मत करो" जवाब। नीचे "इस तरह से करो" है।
मिशैल Micrajer

2
किसी ने Numpy पर लोगों को बताना चाहिए! वे सापेक्ष आयात के एक टन का उपयोग करते हैं!
ऑस्टिन ए

12
यह उत्तर पायथन के वर्तमान संस्करणों पर लागू नहीं है। उद्धृत भाग अब PEP 8 में नहीं पाया जा सकता है। आजकल यह पढ़ता है: "स्पष्ट सापेक्ष आयात पूर्ण आयात के लिए एक स्वीकार्य विकल्प है, खासकर जब जटिल पैकेज लेआउट से निपटना जहां निरपेक्ष आयात का उपयोग करना अनावश्यक रूप से
क्रिया

8

एक रिश्तेदार आयात करना फरार होना ठीक है! यहाँ क्या छोटा है 'मुझे ओल

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py

1
लेकिन आप बेहतर जानते हैं कि sys.argv [0] वास्तव में किस ओर इशारा कर रहा है - यह (पूरी तरह से) वह निर्देशिका नहीं है, जब आपने अजगर की शुरुआत की थी।
कार्ल जूल

यह एक त्वरित हैक है, जिसमें बहुत सारे नुकसान हैं। लेकिन सवाल भी बेहतर नहीं था।
साशा गॉटफ्रेड 19

1
यह स्पष्ट रूप से लिखा गया है, लेकिन डेव के जवाब में मूल हैक बेहतर है, क्योंकि यह __file__वर्तमान फ़ाइल से उचित संबंध प्राप्त करने के लिए उपयोग करता है
जॉन नेउह

4

डिफ़ॉल्ट आयात विधि पहले से ही "रिश्तेदार" है, PYTHONPATH से। PYTHONPATH मूल स्रोत फ़ाइल के फ़ोल्डर के साथ कुछ सिस्टम लाइब्रेरी के लिए डिफ़ॉल्ट रूप से है। यदि आप एक मॉड्यूल को चलाने के लिए -m के साथ चलते हैं, तो वर्तमान निर्देशिका PYTHONPATH में जुड़ जाती है। इसलिए यदि आपके प्रोग्राम का एंट्री पॉइंट Proj के अंदर है, तो उपयोग करके import Common.CommonServer.py और Client.py दोनों के अंदर काम करना चाहिए।

एक रिश्तेदार आयात मत करो। यह काम नहीं करेगा कि आप इसे कैसे चाहते हैं।


1
यदि यह सच है, तो शीर्ष उत्तर यह क्यों नहीं कह रहे हैं? यह काम करेगा या नहीं?
अनाम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.