एक रिश्तेदार पथ से एक मॉड्यूल आयात करें


759

मैं एक पायथन मॉड्यूल को कैसे आयात करूं जो उसके सापेक्ष पथ को बताए?

उदाहरण के लिए, यदि dirFooहोता है Foo.pyऔर dirBar, और dirBarहोता है Bar.py, मैं कैसे आयात कर सकता हूँ Bar.pyमें Foo.py?

यहाँ एक दृश्य प्रतिनिधित्व है:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Fooशामिल करने की इच्छा है Bar, लेकिन फ़ोल्डर पदानुक्रम का पुनर्गठन एक विकल्प नहीं है।


2
Stackoverflow.com/questions/72852/…, जैसे दिख सकते हैं?
Joril

3
मेरे उत्तर की जांच करें, यह अब तक का सबसे पूर्ण है, अन्य विशेष मामले में काम नहीं कर रहे हैं, उदाहरण के लिए जब आप स्क्रिप्ट को किसी अन्य निर्देशिका से या किसी अन्य पायथॉन स्क्रिप्ट से कॉल करते हैं। देखें stackoverflow.com/questions/279237/…
sorin

मुझे भी इसी तरह की समस्या थी और मैंने यह पाया और यह काम करता है !! apt-get install अजगर-प्रोफाइलर
ldcl289

5
बस अगर कोई इसे वैधानिक रूप से करना चाहता है और यहाँ पहुँच जाता है (जैसे मैंने किया :) आप PYTHONPATH पर्यावरण चर
okaram

बेहतर है कि प्रत्येक मामले के लिए Lib / site.py में निर्देशों का पालन किया जाए
Avenida Gez

जवाबों:


333

यह मानते हुए कि आपके दोनों निर्देशिका वास्तविक पायथन पैकेज हैं ( __init__.pyउनके अंदर फ़ाइल है), यहाँ स्क्रिप्ट के स्थान के लिए अपेक्षाकृत मॉड्यूल को शामिल करने के लिए एक सुरक्षित समाधान है।

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

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

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

चेतावनी! मैं वास्तव में नहीं जानता कि क्या हो रहा है जब वर्तमान मॉड्यूल एक eggफ़ाइल के अंदर है । यह शायद विफल भी हो जाता है।


5
क्या मुझे इस बारे में स्पष्टीकरण मिल सकता है कि यह कैसे काम करता है? मुझे एक समान समस्या मिली है और मैं एक खोज को चलाने के बजाय एक अजगर मॉड्यूल डीआईआर को मजबूर करने के लिए प्यार करता हूं
कार्ल क्रेट

रनिंग विन 7 प्रो 64x और पायथन 2.7 मुझे कुछ त्रुटियां हैं। 1) मुझे आयात सूची में निरीक्षण जोड़ना था। 2) ट्यूपल में 1 मान, [0], एक खाली स्ट्रिंग है। दूसरा, [1], फ़ाइल नाम दिखाता है। मैं अनुमान लगा रहा हूं कि पहला रास्ता होना चाहिए ... कोई विचार?
एडम लुईस

2
आप एक सबफ़ोल्डर के लिए जा रहे हैं, तो इसका उपयोग इस प्रकार: os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]) + "/subfolder")Do नहीं से पहले सबफ़ोल्डर जोड़ते abspathके रूप में इस गंभीर बग का कारण बनता है।
मैक्सिमिलियन हिल्स

4
@ scr4ve आपको इसके बजाय os.path.join () का उपयोग करना चाहिए, और cmd_subfolderमेरे जवाब में सीधे केस ( ) जोड़ने का आपका स्वागत है । धन्यवाद!
सोरिन

7
मेरे लिए realpathपहले से ही पूर्ण पथ उत्पन्न करता है, इस प्रकार मुझे आवश्यकता नहीं है abspathos.path.dirnameइंडेक्सिंग को [0]अप्रचलित बनाने के अलावा , विभाजन के बजाय इसका उपयोग किया जा सकता है । फिर लाइन होगी:os.path.realpath(os.path.dirname(inspect.getfile(inspect.currentframe())))
ted

328

सुनिश्चित करें कि dirBar में __init__.pyफ़ाइल है - यह पायथन पैकेज में एक निर्देशिका बनाता है।


204
ध्यान दें कि यह फ़ाइल पूरी तरह से खाली हो सकती है।
हार्ले होलकोम्बे

47
यदि dirBar की मूल निर्देशिका में नहीं है sys.pathतो की उपस्थिति __init__.pyमें dirBarनिर्देशिका ज्यादा मदद नहीं करता है।
22:10 पर jfs

7
-1, जोड़ना __init.py__तभी काम करेगा जब डायरेक्टरी पहले से ही sys.path में हो और मेरे मामले में ऐसा नहीं था। "सोरिन" (स्वीकृत एक) द्वारा समाधान हमेशा काम करता है।
Czarek Tomczak

12
"जब निर्देशिका पहले से ही sys.path में है"। जबकि पूरी तरह से सच है, हम कैसे अनुमान लगा सकते हैं कि निर्देशिका sys.pathसवाल से नहीं थी ? शायद वहाँ कुछ छोड़ा गया था जिसके बारे में हमने देखा या नहीं जाना था?
एस.लॉट

4
यह NO के द्वारा प्रश्न का उत्तर है: चाहे या नहीं आरंभीकरण फ़ाइल वहाँ है, यह उप-निर्देशिका में अजगर देखो नहीं करता है। सैकड़ों उत्थान कैसे हुए?
gent

261

आप अपने पाइथन पथ में उपनिर्देशिका भी जोड़ सकते हैं ताकि यह एक सामान्य स्क्रिप्ट के रूप में आयात हो।

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar

6
ऐसा लगता है कि आपका जवाब रिश्तेदार रास्तों से काम नहीं करता है, देखें stackoverflow.com/questions/279237/…
bogdan

24
यह रिश्तेदार रास्तों के साथ काम करता है - आपको बस यह समझने की ज़रूरत है कि एक रिश्तेदार पथ इस बात पर निर्भर करेगा कि आप किस निर्देशिका से चलते हैं, जो एक त्वरित हैक के अलावा किसी भी चीज़ के लिए एक खराब समाधान बनाता है।
नोबार

12
आप कुछ ऐसा कर सकते हैंsys.path.append(os.path.dirname(__file__) + "/relative/path/to/module")
फाल्को

याsys.path.append(__name__ if __name__ != '__main__' else __loader__.fullname)
१im

1
उपयोग करने पर विचार करें sys.path.insert(0, <path to dirFoo>)क्योंकि यह इसी नाम के मॉड्यूल को कहीं और संग्रहीत करने से पहले इस मॉड्यूल को लोड करेगा।
एंटोन तारसेंको

117
import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule

2
मुझे यह पसंद है क्योंकि आपके पास एक निर्देशिका को ऊपर जाने का लचीलापन है।
चार्ल्स एल।

21
आपको os.path.join()'/' से जुड़ने के बजाय उपयोग करना चाहिए , जो (लंगड़ा) खिड़कियों में टूट जाएगा।
0xc0de

18
यह विश्वसनीय नहीं है। यह इस बात पर निर्भर करता है कि वर्तमान में जो भी वर्किंग डायरेक्टरी है, वह उस डायरेक्टरी पर नहीं जो स्क्रिप्ट में रहती है।
jamesdlin

यदि पथ पहले से ही पथ में नहीं है, तो केवल जोड़ना चाहते हैं। lib_path = os.path.abspath ('../ फ़ंक्शन') यदि lib_path sys.path में नहीं है: sys.path.append (lib_path)
ब्रेंट

@jamesdlin के जवाब में कुछ जवाब मिला: किस बारे में os.path.abspath(os.path.join(__file__,'..','lib'))?
मैथ्यू डेविस

107

बस एक अलग फ़ोल्डर से .py फ़ाइल आयात करने के लिए सरल चीजें करें।

मान लीजिए कि आपके पास एक निर्देशिका है:

lib/abc.py

फिर नाम के रूप में बस एक खाली फ़ाइल को lib फ़ोल्डर में रखें

__init__.py

और फिर उपयोग करें

from lib.abc import <Your Module name>

__init__.pyफ़ाइल को आयात मॉड्यूल के पदानुक्रम के प्रत्येक फ़ोल्डर में रखें ।


79

यदि आप अपनी परियोजना को इस तरह से बनाते हैं:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

तो Foo.py से आप करने में सक्षम होना चाहिए:

import dirFoo.Foo

या:

from dirFoo.Foo import FooObject

टॉम की टिप्पणी के अनुसार, इसके लिए यह आवश्यक है कि srcफ़ोल्डर पहुंच योग्य हो site_packagesया आपके खोज पथ से। इसके अलावा, जैसा कि वह उल्लेख करता है, __init__.pyजब आप पहली बार उस पैकेज / निर्देशिका में एक मॉड्यूल आयात करते हैं, तो इसका आयात किया जाता है। आमतौर __init__.pyपर बस एक खाली फाइल है।


यह भी उल्लेख करें कि init .py तब आयात किया जाता है जब उस पैकेज के अंदर पहला मॉड्यूल आयात किया जाता है। इसके अलावा, आपका उदाहरण केवल तभी काम करेगा जब src साइट_पैकेज (या खोज पथ) में हो
टॉम

3
यह सबसे सरल उपाय है जिसकी मुझे तलाश थी। यदि आयात करने के लिए फ़ाइल सबडिरेक्टरीज में से एक में होना निश्चित है, तो यह समाधान एक रत्न है।
दीपक जीएम

मैंने एक ही कोशिश की है और असफल रहा हूं। मुझे नहीं पता क्यों। ImportError: कस्टम मॉड्यूल नाम का कोई मॉड्यूल नहीं
मिंग ली

9
क्यों कोई Foo.py के भीतर से Foo आयात करना चाहता है। मुझे लगता है कि Bar.py से होना चाहिए।
bhaskarc

from dirFoo import Fooकहने के लिए Foo.bla()। अगर import dirFoo.Fooएक का उपयोग करना चाहिए dirFoo.Foo.bla()- ऊंट मामले के बिना भी बहुत बदसूरत।
सेस टिम्मरमैन

45

सबसे आसान तरीका sys.path.append () का उपयोग करना है।

हालांकि, आप भी छोटा सा भूत मॉड्यूल में रुचि हो सकती है । यह आंतरिक आयात कार्यों तक पहुंच प्रदान करता है।

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

यह मॉड्यूल को गतिशील रूप से लोड करने के लिए उपयोग किया जा सकता है जब आप एक मॉड्यूल का नाम नहीं जानते हैं।

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

इसके अलावा, ये कार्य उपयोगी हो सकते हैं:

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)

ध्यान दें कि प्रलेखन में imp.load_source और imp.load_compiled को अप्रचलित के रूप में सूचीबद्ध किया गया है। इसके बजाय imp.find_module और imp.load_module अनुशंसित हैं।
एमक्टास

@amicitas, क्या आप इसके लिए कोई संदर्भ प्रदान कर सकते हैं (मुझे इसकी आवश्यकता है, और मैं अजगर 2.6 का उपयोग कर रहा हूं। मुझे पता है कि 2.7 डॉक्स इन के बारे में क्या कहते हैं, लेकिन 2.6 के बारे में कोई संदर्भ नहीं पा सके)
0xc0de

@ 0xc0de आप यह विवरण पा सकते हैं कि दोनों मॉड्यूल के लिए डॉक्स 2.7.3 और अजगर 2.6.7 दोनों के लिए डॉक्स में । ऐसा लगता है कि उन कार्यों को अजगर 3.2 के लिए डॉक्स में भी नहीं हैं।
21

1
पायथन 3.3 में इस तरह की सोर्स फाइल्स को इम्पोर्ट करने के लिए, एयट्रिस्चुअल पाइथन सोर्स फाइल इम्पोर्ट करें देखें (पायथन 3.3+) - स्टैक ओवरफ्लो । धन्यवाद, यहाँ सुझावों के लिए दोस्तों।
nealmcb

44

यह प्रासंगिक पीईपी है:

http://www.python.org/dev/peps/pep-0328/

विशेष रूप से, प्रकल्पित dirFoo dirBar से एक निर्देशिका है ...

DirFoo \ Foo.py में:

from ..dirBar import Bar

यह मेरे लिए काम कर रहा है, बस हर फ़ोल्डर पर init .py जोड़ा और आयात करने के लिए सफलता
yussan

23

अपनी स्क्रिप्ट में किसी भी संशोधन के बिना सबसे आसान तरीका है PYTHONPATH पर्यावरण चर सेट करना। क्योंकि sys.path इन स्थानों से आरंभ किया गया है:

  1. इनपुट स्क्रिप्ट (या वर्तमान निर्देशिका) वाली निर्देशिका।
  2. PYTHONPATH (निर्देशिका नामों की एक सूची, शेल वैरिएबल PATH के समान सिंटैक्स के साथ)।
  3. स्थापना-निर्भर डिफ़ॉल्ट।

बस दौडो:

export PYTHONPATH=/absolute/path/to/your/module

आप sys.path में ऊपर का पथ होगा, जैसा कि नीचे दिखाया गया है:

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']

13

मेरी राय में सबसे अच्छा विकल्प फ़ोल्डर में __ init __.py रखना और फ़ाइल को कॉल करना है

from dirBar.Bar import *

यह sys.path.append () का उपयोग करने के लिए अनुशंसित नहीं है क्योंकि यदि आप मौजूदा अजगर पैकेज के समान फ़ाइल नाम का उपयोग करते हैं तो कुछ गलत हो सकता है। मैंने परीक्षण नहीं किया है, लेकिन यह अस्पष्ट होगा।


अजीब है कि from dirBar.Bar import *काम करता है, लेकिन नहीं from dirBar.Bar import Bar। क्या आप जानते हैं कि * क्यों काम करता है? क्या होगा अगर मेरे पास dirBar में कई फाइलें थीं / और उनमें से केवल कुछ को हथियाना चाहता था (आपके द्वारा यहां पोस्ट की गई विधि जैसी विधि का उपयोग करके)?
परीक्षक

2
@tester: उपयोग करें from dirBar import Bar
नोबार

@ कारण यह fromहै कि स्रोत को इंगित करता है, और importउस स्रोत से हड़पने के बाद सब कुछ है। from dirBar.Bar import Barइसका मतलब है "स्रोत से, स्रोत को ही आयात करें", जिसका कोई मतलब नहीं है। *हालांकि इसका मतलब है, "मुझे स्रोत से सब कुछ दे"
FuriousFolder

11

लिनक्स उपयोगकर्ताओं के लिए त्वरित और गंदा तरीका है

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

ln -s (path)/module_name.py

या

ln -s (path)/package_name

नोट: एक "मॉड्यूल" किसी भी फ़ाइल में एक .py एक्सटेंशन के साथ है और एक "पैकेज" किसी भी फ़ोल्डर में फ़ाइल होती है __init__.py(जिसमें एक खाली फ़ाइल हो सकती है)। उपयोग के दृष्टिकोण से, मॉड्यूल और पैकेज समान हैं - दोनों importकमांड के माध्यम से अनुरोध के अनुसार अपनी निहित "परिभाषाओं और बयानों" को उजागर करते हैं ।

देखें: http://docs.python.org/2/tutorial/modules.html


10
from .dirBar import Bar

के बजाय:

from dirBar import Bar

बस एक और dirBar स्थापित किया जा सकता है और एक foo.py पाठक को भ्रमित कर सकता है।


2
मैं खिड़कियों पर ऐसा करने में सक्षम नहीं था। क्या यह लिनक्स पर है?
गेब्रियल

1
यह फू आयात करने वाली स्क्रिप्ट से काम करेगा। यानी: main.py आयात dirFoo.Foo। यदि आप स्क्रिप्ट के रूप में Foo.py चलाने का प्रयास कर रहे हैं, तो यह विफल हो जाएगा। देखें stackoverflow.com/questions/72852/...
jgomo3

9

इस मामले के लिए बारकोड को Foo.py में आयात करने के लिए, पहले मैं इन फ़ोल्डरों को पायथन पैकेज में बदल दूंगा जैसे:

dirFoo\
    __init__.py
    Foo.py
    dirBar\
        __init__.py
        Bar.py

तब मैं इसे इस तरह से करूंगा Foo.py:

from .dirBar import Bar

अगर मैं नाम स्थान को बार की तरह देखना चाहता था। जो भी , या

from . import dirBar

अगर मैं नाम स्थान dirBar.Bar चाहता था। जो भी हो । यदि आप dirBar पैकेज के तहत अधिक मॉड्यूल रखते हैं तो यह दूसरा मामला उपयोगी है।


7

__Init__.py फ़ाइल जोड़ें :

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

फिर इस कोड को Foo.py की शुरुआत में जोड़ें:

import sys
sys.path.append('dirBar')
import Bar

5
यदि dirBarपहले से ही एक अजगर पैकेज (अस्तित्व के अनुसार dirBar/__init__.py) है, तो इसके लिए अपील dirBarकरने की कोई आवश्यकता नहीं है sys.path, नहीं? import Barसे कथन Foo.pyको पर्याप्त होना चाहिए।
सांता

5

रिश्तेदार sys.path उदाहरण:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

इस उत्तर के आधार पर


5

ठीक है, जैसा कि आप उल्लेख करते हैं, आमतौर पर आप अपने मॉड्यूल के साथ एक फ़ोल्डर तक पहुंच चाहते हैं जहां आपकी मुख्य स्क्रिप्ट चलती है, इसलिए आप उन्हें आयात करते हैं।

समाधान:

मेरे पास स्क्रिप्ट D:/Books/MyBooks.pyऔर कुछ मॉड्यूल हैं (जैसे कि oldies.py)। मुझे उपनिर्देशिका से आयात करने की आवश्यकता है D:/Books/includes:

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

एक जगह print('done')में oldies.py, ताकि इसकी पुष्टि की सब कुछ ठीक चल रहा है। यह तरीका हमेशा काम करता है क्योंकि पायथन परिभाषा द्वाराsys.path प्रोग्राम स्टार्टअप पर प्रारंभिक रूप , इस सूची का पहला आइटम path[0], वह निर्देशिका है जिसमें स्क्रिप्ट शामिल है जिसका उपयोग पायथन दुभाषिया को आमंत्रित करने के लिए किया गया था।

यदि स्क्रिप्ट निर्देशिका उपलब्ध नहीं है (उदाहरण के लिए यदि इंटरप्रेन्योर को अंतःक्रियात्मक रूप से आमंत्रित किया जाता है या यदि स्क्रिप्ट को मानक इनपुट से पढ़ा जाता है), path[0]तो खाली स्ट्रिंग है, जो पहले पायथन को वर्तमान निर्देशिका में खोज मॉड्यूल को निर्देशित करता है। ध्यान दें कि स्क्रिप्ट निर्देशिका को सम्मिलित करने से पहले प्रविष्ट किया जाता है PYTHONPATH


1
मुझे site.addsitedir(sys.path[0]+'/includes')अपने पहले सरल पायथन प्रोग्राम ब्रेक_टाइम में दो बैकस्लैश (यानी ) के बजाय एक फॉरवर्ड स्लैश का उपयोग करना था : https://github.com/ltfschoen/PythonTest । मैं सिस्टम का उपयोग करता हूं: MacOS v10.11.5, पायथन 2.7.12, आइडल आईडीई 2.7.12, टीके 8.5.9
ल्यूक स्कोन

4

बस आप उपयोग कर सकते हैं: from Desktop.filename import something

उदाहरण:

यह देखते हुए कि फ़ाइल test.pyनिर्देशिका में नाम है Users/user/Desktop, और हमेशा के लिए आयात करेगी।

कोड:

from Desktop.test import *

लेकिन सुनिश्चित करें कि आप __init__.pyउस निर्देशिका में " " नामक एक खाली फ़ाइल बनाते हैं


1
तारांकित आयात के खिलाफ सलाह दी जाती है। देखें: stackoverflow.com/questions/2386714/why-is-import-bad
axolotl

मुझे पता है कि मैंने पहले क्यों लिखा था, इसलिए मैंने import somethingइसे आसान बनाने के लिए कहा * मूल रूप से राम के लिए अच्छा नहीं है और यह भी कि अगर 2 कार्यों का एक ही नाम है तो यह आपके कोड को बड़े पैमाने पर देगा
0x1996

3

एक और उपाय यह होगा कि आप पी-आवश्यकता पैकेज को स्थापित करें और फिर निम्नलिखित का उपयोग करेंFoo.py

import require
Bar = require('./dirBar/Bar')

URL वास्तव में pypi.org/project/require.py लगता है , और ध्यान दें कि इसे पिप के माध्यम से इंस्टॉल करने की आवश्यकता है।
फ्लैश शेरिडन

1
@FlashSheridan नहीं, यह एक अलग परियोजना है। मैंने पाई-आवश्यकता को हटा दिया क्योंकि मुझे यकीन था कि कोई भी इसका उपयोग नहीं कर रहा था, हालांकि मैंने इस पोस्ट के बारे में नहीं सोचा था। यदि आपको अभी भी एक require()फ़ंक्शन की आवश्यकता है , तो आप मेरे Node.py परियोजना पर एक नज़र डाल सकते हैं: github.com/nodepy/nodepy
Niklas R

2

यहां एक पथ को एक स्तर से ऊपर आयात करने का एक तरीका है, रिश्तेदार पथ का उपयोग करके।

असल में, कार्यशील निर्देशिका को एक स्तर (या किसी भी सापेक्ष स्थान) पर ले जाएं, उसे अपने पथ में जोड़ें, फिर कार्यशील निर्देशिका को उस स्थान पर वापस ले जाएं जहां आपने शुरुआत की थी।

#to import from one level above:
cwd = os.getcwd()
os.chdir("..")
below_path =  os.getcwd()
sys.path.append(below_path)
os.chdir(cwd)

1
मैं तुम्हें यहाँ तर्क नहीं समझता। यह अधिक जटिल है
ट्रांसिलवैलड

0

मुझे अजगर के बारे में अनुभव नहीं है, इसलिए यदि मेरे शब्दों में कोई गलत है, तो मुझे बताएं। यदि आपकी फ़ाइल पदानुक्रम इस तरह व्यवस्थित है:

project\
    module_1.py 
    module_2.py

module_1.pyएक समारोह में कहा जाता को परिभाषित करता है func_1(), module_2.py :

from module_1 import func_1

def func_2():
    func_1()

if __name__ == '__main__':
    func_2()

और आप python module_2.pycmd में चलते हैं , यह वही करेगा जो func_1()परिभाषित करता है। आमतौर पर हम समान पदानुक्रम फ़ाइलों को आयात करते हैं। लेकिन जब आप लिखते from .module_1 import func_1हैं module_2.py, तो अजगर दुभाषिया कहेगा No module named '__main__.module_1'; '__main__' is not a package। तो इसे ठीक करने के लिए, हम बस हमारे द्वारा किए गए बदलाव को जारी रखते हैं, और दोनों मॉड्यूल को एक पैकेज में स्थानांतरित करते हैं, और चलाने के लिए एक कॉलर के रूप में तीसरा मॉड्यूल बनाते हैं module_2.py

project\
    package_1\
        module_1.py
        module_2.py
    main.py

main.py :

from package_1.module_2 import func_2

def func_3():
    func_2()

if __name__ == '__main__':
    func_3()

लेकिन कारण है कि हम एक जोड़ने .से पहले module_1में module_2.pyहै कि अगर हम चाहते हैं कि और रन नहीं करते है main.py, अजगर दुभाषिया कहेंगे No module named 'module_1', कि एक छोटे से मुश्किल है, module_1.pyठीक बगल है module_2.py। अब मैं कुछ करने func_1()देता module_1.pyहूँ:

def func_1():
    print(__name__)

वह __name__रिकॉर्ड जो func_1 को कॉल करता है। अब हम .पहले वाले को रखते हैं module_1, चलाते हैं main.py, छापेंगे package_1.module_1, नहीं module_1। यह इंगित करता है कि जो कॉल करता func_1()है, वह उसी पदानुक्रम पर है main.py, जो .कि module_1उसी पदानुक्रम पर है जो module_2.pyस्वयं के रूप में है। इसलिए यदि कोई बिंदी नहीं है, तो उसी पदानुक्रम को स्वयं के रूप में main.pyपहचान लेगा module_1, यह पहचान सकता है package_1, लेकिन इसे "अंडर" नहीं।

अब इसे थोड़ा जटिल बनाते हैं। आपके पास एक config.iniमॉड्यूल है और एक फ़ंक्शन को उसी पदानुक्रम में 'main.py' के रूप में पढ़ने के लिए परिभाषित करता है।

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
    main.py

और किसी अपरिहार्य कारण के लिए, आपको इसे कॉल करना होगा module_2.py, इसलिए इसे ऊपरी पदानुक्रम से आयात करना होगा। मॉड्यूल_2 थिंकपैड :

 import ..config
 pass

दो डॉट्स का मतलब है ऊपरी पदानुक्रम (तीन डॉट्स ऊपरी से ऊपरी तक पहुंच, और इसी तरह) से आयात। अब हम चलाते हैं main.py, दुभाषिया कहेंगे ValueError:attempted relative import beyond top-level package:। यहाँ पर "शीर्ष-स्तरीय पैकेज" है main.py। बस क्योंकि config.pyबगल में है main.py, वे एक ही पदानुक्रम में हैं, config.py"अंडर" नहीं है main.py, या यह "लीड" नहीं है main.py, इसलिए यह परे है main.py। इसे ठीक करने के लिए, सबसे सरल तरीका है:

project\
    package_1\
        module_1.py
        module_2.py
    config.py
    config.ini
main.py

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


-5

यह भी काम करता है, और sysमॉड्यूल के साथ किसी भी चीज़ की तुलना में बहुत सरल है :

with open("C:/yourpath/foobar.py") as f:
    eval(f.read())

1
यदि ओपी एक मार्ग को हार्डकोड करने जा रहा था, तो वे वैसे भी PYTHONPATH में उस पथ को सम्मिलित कर सकते थे। मुझे लगता है कि यह बिंदु इस तरह से कर रहा है कि एक मार्ग को हार्डकोड नहीं करता है क्योंकि यह कहीं और टूट जाएगा।
मैथ्यू

-15

मुझे अत्यधिक सावधानी से बुलाएं, लेकिन मुझे मेरा और अधिक पोर्टेबल बनाना पसंद है क्योंकि यह मान लेना असुरक्षित है कि फाइलें हमेशा हर कंप्यूटर पर एक ही स्थान पर रहेंगी। व्यक्तिगत रूप से मेरे पास कोड है जो पहले फ़ाइल पथ को देखता है। मैं लिनक्स का उपयोग करता हूं इसलिए मेरा ऐसा दिखेगा:

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

जब तक आप इनको एक साथ पैकेज करने की योजना नहीं बनाते हैं। लेकिन अगर ऐसा है तो आपको वास्तव में दो अलग-अलग फ़ाइलों की आवश्यकता नहीं है।


11
सुपर अक्षम!
0xc0de

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