python - मूल फ़ोल्डर से मॉड्यूल आयात करना




module path (12)

आप sys.path में सूचीबद्ध "मॉड्यूल खोज पथ" में पथ के आधार पर ओएस का उपयोग कर सकते हैं। तो आप आसानी से निम्नलिखित जैसे मूल निर्देशिका जोड़ सकते हैं

import sys
sys.path.insert(0,'..')

यदि आप पैरेंट-पैरेंट निर्देशिका जोड़ना चाहते हैं,

sys.path.insert(0,'../..')

मैं पाइथन 2.5 चला रहा हूँ।

यह मेरा फ़ोल्डर पेड़ है:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(मेरे पास प्रत्येक फ़ोल्डर में __init__.py भी है, जो पठनीयता के लिए यहां छोड़ा गया है)

मैं life मॉड्यूल के अंदर से nib मॉड्यूल कैसे आयात करूं? मुझे उम्मीद है कि sys.path के साथ tinkering बिना करना संभव है।

नोट: मुख्य मॉड्यूल चल रहा है ptdraft फ़ोल्डर में है।


आप sys के लिए अपनी निर्देशिका पथ जोड़ सकते हैं

import sys
import os
sys.path.append(os.path.__file__)


उत्तर को समझने के लिए यहां एक छोटा, सरल, आशाजनक रूप से आसान है, यह क्रॉस-प्लेटफॉर्म है
(विभिन्न ऑपरेटिंग सिस्टम पर काम करना चाहिए) क्योंकि यह केवल अंतर्निहित मॉड्यूल का उपयोग करता है।
पाइथन कई ओएस-एसएस और os लिए डिज़ाइन किया गया है, sys और inspect इसका हिस्सा हैं इसलिए भी होना चाहिए।

मेरे उत्तर के लिए कोड (लंबा संस्करण) :

from inspect import getsourcefile
import os.path
import sys

current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]

sys.path.insert(0, parent_dir)

import my_module  # Change name here.

यह स्टैक ओवरफ़्लो उत्तर से कुछ जानकारी का उपयोग करता है मैं वर्तमान का मार्ग कैसे प्राप्त करूं
पायथन में निष्पादित फ़ाइल? अंतर्निहित उपकरण के साथ वर्तमान में चल रहे कोड का स्रोत ढूंढने के लिए।

from inspect import getsourcefile  
from os.path import abspath  

अगला, जहां भी आप स्रोत स्रोत को ढूंढना चाहते हैं, बस इसका उपयोग करें:

abspath(getsourcefile(lambda:0))

मेरा कोड पाइथन पथ सूची ( sys.path ) में फ़ाइल पथ आइटम जोड़ता है ताकि पायथन आयात कर सके
उस स्थान से मॉड्यूल। एक नई लाइन पर कोड sys.path.pop(0) को चलाने का अच्छा विचार है
उपरोक्त कोड में एक मॉड्यूल आयात करने के बाद, जब निर्देशिका में जोड़ा गया एक मॉड्यूल होता है
प्रोग्राम में बाद में आयात किए गए एक और मॉड्यूल के समान नाम के साथ।
अन्य पथों को हटाने से बचने के लिए आपको आयात से पहले जोड़े गए एक ही आइटम को हटाने की आवश्यकता है।

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

उत्तर के लिए छोटा कोड - कम लाइनें और चर:

from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module    # Replace "my_module" here with your module's name.
sys.path.pop(0)

कम लाइनों के लिए, दूसरी लाइन को import os.path as path, sys, inspect ,
फिर पहली पंक्ति को हटा दें और inspect. जोड़ें inspect. getsourcefile (तीसरी पंक्ति) की शुरुआत में।
- हालांकि यह सभी मॉड्यूल आयात करता है इसलिए अधिक समय, स्मृति और संसाधनों की आवश्यकता हो सकती है।

वैकल्पिक स्थान विधि के बारे में नोट्स:

मेरा उत्तर कोड चलाने के फ़ाइल पथ प्राप्त करने के लिए __file__ चर का उपयोग नहीं करता है
क्योंकि यहां उपयोगकर्ताओं ने अक्सर इसे अविश्वसनीय बताया है। आपको इसका इस्तेमाल करने से बचना चाहिए
अन्य लोगों द्वारा उपयोग किए जाने वाले कार्यक्रमों के अलावा जब समस्याएं उन्हें प्रभावित नहीं कर सकती हैं।
• यह कुछ प्लेटफॉर्म पर नहीं पाया जा सकता है • यह कभी-कभी पूर्ण फ़ाइल पथ नहीं होता है
स्टैक ओवरफ़्लो question से, कुछ उदाहरणों का उद्धरण जहां यह काम करने में विफल रहता है:

  • py2exe __file__ विशेषता नहीं है, लेकिन एक वर्कअराउंड है
  • जब आप execute() साथ IDLE से चलाते हैं execute() कोई __file__ विशेषता नहीं है
  • ओएस एक्स 10.6 जहां मुझे NameError: global name '__file__' is not defined

एक लिनक्स सिस्टम में, आप "जीवन" फ़ोल्डर से nib.py फ़ाइल में एक सॉफ्ट लिंक बना सकते हैं। फिर, आप इसे आसानी से आयात कर सकते हैं:

import nib

ऐसा लगता है कि समस्या किसी मूल निर्देशिका या उस तरह की किसी भी चीज़ में होने वाले मॉड्यूल से संबंधित नहीं है।

आपको उस निर्देशिका को जोड़ने की ज़रूरत है जिसमें PYTHONPATH को ptdraft शामिल है

आपने कहा कि import nib आपके साथ काम करता है, जिसका शायद मतलब है कि आपने ptdraft स्वयं (अपने माता-पिता नहीं) को जोड़ा है।


पिछले उत्तर के रूप में शैली की एक ही तरह - लेकिन कम लाइनों में: पी

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

फ़ाइल उस स्थान को लौटाती है जिसमें आप काम कर रहे हैं


पुस्तकालयों के साथ काम करें। Nib नामक लाइब्रेरी बनाएं, setup.py का उपयोग करके इसे इंस्टॉल करें, इसे साइट-पैकेज में रहने दें और आपकी समस्याएं हल हो जाएं। आपको एक ही पैकेज में जो कुछ भी करना है उसे सामान भरना नहीं है। टुकड़ों को तोड़ो।


मेरे लिए मूल निर्देशिका तक पहुंचने के लिए सबसे छोटा और मेरा पसंदीदा ऑनलाइनर है:

sys.path.append(os.path.dirname(os.getcwd()))

या:

sys.path.insert(1, os.path.dirname(os.getcwd()))

os.getcwd () वर्तमान कार्यशील निर्देशिका का नाम देता है, os.path.dirname (directory_name) पास किए गए के लिए निर्देशिका नाम देता है।

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

एक और तरीका है माता-पिता निर्देशिका को PYTHONPATH सिस्टम पर्यावरण चर में जोड़ना।


यदि आपके मॉड्यूल फ़ोल्डर को PYTHONPATH में जोड़ना काम नहीं करता है, तो आप अपने प्रोग्राम में sys.path सूची को संशोधित कर सकते हैं जहां पाइथन दुभाषिया आयात करने के लिए मॉड्यूल की खोज करता है, पायथन दस्तावेज़ कहता है:

जब स्पैम नामक एक मॉड्यूल आयात किया जाता है, तो दुभाषिया पहले उस नाम के साथ एक अंतर्निहित मॉड्यूल की खोज करता है। यदि नहीं मिला, तो यह variable sys.path द्वारा दी गई निर्देशिकाओं की सूची में spam.py नाम की एक फ़ाइल की खोज करता है। sys.path इन स्थानों से शुरू किया गया है:

  • निर्देशिका जिसमें इनपुट स्क्रिप्ट (या वर्तमान निर्देशिका) है।
  • पायथनपैथ (निर्देशिका नामों की एक सूची, उसी वाक्यविन्यास के साथ खोल परिवर्तनीय पथ)।
  • स्थापना-निर्भर डिफ़ॉल्ट।

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

इसे जानना, आप अपने कार्यक्रम में निम्नलिखित कर सकते हैं:

import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')

# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft

यहां अधिक सामान्य समाधान है जिसमें मूल निर्देशिका में sys.path (मेरे लिए काम करता है) शामिल है:

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

सापेक्ष आयात (जैसे from .. import mymodule ) केवल एक पैकेज में काम करते हैं। 'Mymodule' आयात करने के लिए जो आपके वर्तमान मॉड्यूल की मूल निर्देशिका में है:

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir) 

import mymodule

संपादित करें : __file__ विशेषता हमेशा नहीं दी जाती है। os.path.abspath(__file__) का उपयोग करने के बजाय अब मैंने वर्तमान फ़ाइल के फ़ाइल नाम (और पथ) को पुनर्प्राप्त करने के लिए निरीक्षण मॉड्यूल का उपयोग करने का सुझाव दिया है





python-import