अन्य स्रोत के लिए पायथन खोज पथ का विस्तार करें


106

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

python someprojectfile.py

मुझे मिला

ImportError: no module named core.'somemodule'

मैं अपने सभी आयातों के लिए इसे प्राप्त करता हूं मुझे लगता है कि यह मार्ग के साथ एक मुद्दा है।

TLDR:

मैं पायथन को खोजने के लिए कैसे ~/codez/project/और सभी फ़ाइलों और फ़ोल्डरों को आयात विवरणों के दौरान * .py फ़ाइलों के लिए प्राप्त करता हूं ।

जवाबों:


171

ऐसा करने के कुछ संभावित तरीके हैं:

  • PYTHONPATHआयातित मॉड्यूल के लिए खोज करने के लिए निर्देशिकाओं की एक अलग-अलग सूची के लिए पर्यावरण चर सेट करें ।
  • अपने कार्यक्रम में, उन sys.path.append('/path/to/search')निर्देशिकाओं के नाम जोड़ने के लिए उपयोग करें जिन्हें आप आयातित मॉड्यूल की खोज के लिए पायथन चाहते हैं। sys.pathकेवल निर्देशिकाओं की सूची है पायथन खोजता है हर बार जब इसे एक मॉड्यूल आयात करने के लिए कहा जाता है, और आप इसे आवश्यकतानुसार बदल सकते हैं (हालांकि मैं किसी भी मानक निर्देशिका को हटाने की सिफारिश नहीं करूंगा!)। पायथन शुरू PYTHONPATHहोने पर पर्यावरण चर में आपके द्वारा डाली गई कोई भी निर्देशिका सम्मिलित की जाएगी sys.path
  • site.addsitedirनिर्देशिका को जोड़ने के लिए उपयोग करें sys.path। इसके और सिर्फ सादे एपिंग के बीच का अंतर यह है कि जब आप उपयोग करते हैं addsitedir, तो यह .pthउस निर्देशिका के भीतर फ़ाइलों की तलाश भी करता है और संभवतः sys.pathफ़ाइलों की सामग्री के आधार पर अतिरिक्त निर्देशिकाओं को जोड़ने के लिए उनका उपयोग करता है । अधिक विवरण के लिए दस्तावेज़ देखें।

आप इनमें से किसका उपयोग करना चाहते हैं, यह आपकी स्थिति पर निर्भर करता है। याद रखें कि जब आप अन्य उपयोगकर्ताओं को अपनी परियोजना वितरित करते हैं, तो वे आम तौर पर इसे इस तरह से स्थापित करते हैं कि पायथन कोड फ़ाइलों को पायथन के आयातक द्वारा स्वचालित रूप से पता लगाया जाएगा (यानी पैकेज आमतौर पर site-packagesनिर्देशिका में स्थापित होते हैं ), इसलिए यदि आप sys.pathअपने कोड में गड़बड़ करते हैं । , यह अनावश्यक हो सकता है और उस कोड पर किसी अन्य कंप्यूटर पर चलने पर भी प्रतिकूल प्रभाव पड़ सकता है। विकास के लिए, मैं एक अनुमान लगाता हूं कि सेटिंग PYTHONPATHआमतौर पर जाने का सबसे अच्छा तरीका है।

हालाँकि, जब आप किसी ऐसी चीज़ का उपयोग कर रहे होते हैं, जो सिर्फ आपके ही कंप्यूटर पर चलती है (या जब आपके पास अमानक सेटअप हो, जैसे कभी-कभी वेब ऐप फ्रेमवर्क में), तो ऐसा करना पूरी तरह से असामान्य नहीं है

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

इसलिए अगर मुझे 15 उपनिर्देशिकाएँ पसंद हैं, तो मुझे व्यक्तिगत रूप से प्रत्येक को जोड़ना होगा?
थीमास्ट्रो

और क्या आप PYTHONPATH को बदलने के लिए कमांड लाइन तर्क का एक उदाहरण दे सकते हैं?
थीमैस्ट्रो

3
सेट करने के लिए PYTHONPATH: .bashrcया जो भी स्टार्टअप फ़ाइल आपके शेल का उपयोग करता है (यदि यह बैश नहीं है), लिखें export PYTHONPATH=$PYTHONPATH:$HOME/codez/project। लेकिन अगर आपके पास उपनिर्देशिकाओं का एक समूह है, तो मैं एक .pthफ़ाइल और उपयोग करूँगा site.addsitedir। आप एक मॉड्यूल बना सकते हैं जो sitecustomizeआपके लिए फ़ंक्शन को कॉल कर सकता है; इसे डालने की कोशिश करें ~/.local/lib/python2.6/sitecustomize.py(अपने पायथन संस्करण को स्थानापन्न करें) ताकि यह उम्मीद है कि स्वचालित रूप से आयात हो जाए।
डेविड जेड

मैंने अपनी .bashrc फ़ाइल में निम्नलिखित डाला और मुझे अभी भी उन आयातों के साथ कोई भाग्य नहीं है। कोई विचार? मैं वैसे भी .pth फ़ाइल कैसे बनाऊँगा? निर्यात PYTHONPATH = $ PYTHONPATH: $ HOME / adaifotis / codez / निर्यात PYTHONPATH = $ PYTHONPATH: $ HOME / adaifotis / codez / परियोजना निर्यात PYTHONPATH = $ PYTHONPATH = $ PYTHONPATH = $ PYTHONPATH = $ PYTHONPATH = $ PYTHONPATH HOME / adaifotis / codez / project / proxies Export PYTHONPATH = $ PYTHONPATH: $ HOME / adaifotis / codez / project / conf
themaestro

एक टर्मिनल खोलने और चलाने का प्रयास करें echo $PYTHONPATH। यदि पर्यावरण चर को ठीक से सेट किया गया है, तो आपको निर्देशिकाओं की एक बृहदान्त्र-पृथक सूची देखनी चाहिए। .pthफ़ाइलों के बारे में जानकारी के लिए, उस siteमॉड्यूल के लिए प्रलेखन देखें, जिसे मैंने अपने उत्तर में जोड़ा था। यह आपको बताता है कि सामग्री क्या होनी चाहिए और उनका उपयोग कैसे करना चाहिए।
डेविड जेड

13

: आप भी अजगर संकुल के बारे में यहाँ पढ़ना चाहिए http://docs.python.org/tutorial/modules.html

आपके उदाहरण से, मुझे लगता है कि आपके पास वास्तव में एक पैकेज है ~/codez/project__init__.pyएक अजगर निर्देशिका में फ़ाइल एक नेमस्पेस में एक निर्देशिका मैप करती है। यदि आपकी उपनिर्देशिका सभी में एक __init__.pyफ़ाइल है, तो आपको केवल आधार निर्देशिका को अपने साथ जोड़ना होगा PYTHONPATH। उदाहरण के लिए:

PYTHONPATH = $ PYTHONPATH: $ घर / adaifotis / परियोजना

अपने PYTHONPATH पर्यावरण चर का परीक्षण करने के अलावा, जैसा कि डेविड बताते हैं, आप इस तरह से अजगर में इसका परीक्षण कर सकते हैं:

$ python
>>> import project                      # should work if PYTHONPATH set
>>> import sys
>>> for line in sys.path: print line    # print current python path

...


आप अपने __init__.pybackticks में डाल करने के लिए यह स्पष्ट रूप से आप वास्तव में मतलब है __init__.py, के रूप में विरोध करना चाहते हो सकता है init.py। बस भ्रमित करने वाले न्यूबियों से बचें। :)
19'15

4

मुझे पता है कि यह धागा थोड़ा पुराना है, लेकिन इस दिल को पाने में मुझे कुछ समय लगा, इसलिए मैं साझा करना चाहता था।

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

from modules.report import report, reportError

अगर मैं अपनी मुख्य स्क्रिप्ट कहता हूं, तो यह काम करता है। फिर भी, मैं प्रत्येक मॉड्यूल main()को प्रत्येक में शामिल करके, और प्रत्येक को सीधे कॉल करके, जैसे:

python modules/report.py

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

मुझे लगता है कि इसका सबसे साफ समाधान यह है कि शीर्ष पर इसे शामिल करके पायथन खोज पथ में CWD को जोड़ा जाए:

import sys

sys.path.append(".")

अब पायथन सीडब्ल्यूडी (वर्तमान निर्देशिका) को खोजता है, "मॉड्यूल" सब-फ़ोल्डर पाता है, और सब कुछ ठीक है।


3

मैंने इस प्रश्न को उत्तर की तलाश में पढ़ा, और उनमें से कोई भी पसंद नहीं किया।

इसलिए मैंने एक त्वरित और गंदा समाधान लिखा। बस इसे कहीं अपने sys.path पर रखें, और यह किसी भी निर्देशिका को folder(वर्तमान कार्यशील निर्देशिका से) या इसके अंतर्गत जोड़ देगा abspath:

#using.py

import sys, os.path

def all_from(folder='', abspath=None):
    """add all dirs under `folder` to sys.path if any .py files are found.
    Use an abspath if you'd rather do it that way.

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree.
    With that, try not to use this on something too close to '/'

    """
    add = set(sys.path)
    if abspath is None:
        cwd = os.path.abspath(os.path.curdir)
        abspath = os.path.join(cwd, folder)
    for root, dirs, files in os.walk(abspath):
        for f in files:
            if f[-3:] in '.py':
                add.add(root)
                break
    for i in add: sys.path.append(i)

>>> import using, sys, pprint
>>> using.all_from('py') #if in ~, /home/user/py/
>>> pprint.pprint(sys.path)
[
#that was easy
]

और मुझे यह पसंद है क्योंकि मेरे पास कुछ रैंडम टूल के लिए एक फ़ोल्डर हो सकता है और उनके पास पैकेज या किसी भी चीज़ का हिस्सा नहीं होना चाहिए, और कोड की एक जोड़ी लाइनों में अभी भी उनमें से कुछ (या सभी) तक पहुंच प्राप्त करें।


3

मेरे द्वारा खोजने का सबसे आसान तरीका "any_name.pth" फ़ाइल बनाना और इसे आपके फ़ोल्डर "\ Lib \ site- पैकेज" में डालना है। आपको उस फ़ोल्डर को ढूंढना चाहिए जहां अजगर स्थापित है।

उस फ़ाइल में, निर्देशिकाओं की एक सूची रखें जहाँ आप आयात के लिए मॉड्यूल रखना चाहते हैं। उदाहरण के लिए, उस फाइल में इस तरह से एक लाइन बनाएं:

C: \ Users \ उदाहरण ... \ उदाहरण

अजगर में इसे चलाकर आप इसे बता पाएंगे:

import sys
for line in sys: print line

आप अपनी निर्देशिका को अन्य लोगों के बीच प्रिंट आउट देखेंगे, जहाँ से आप आयात भी कर सकते हैं। अब आप "mymodule.py" फ़ाइल आयात कर सकते हैं जो उस निर्देशिका में आसानी से उपलब्ध है:

import mymodule

यह सबफ़ोल्डर आयात नहीं करेगा। उसके लिए आप एक python स्क्रिप्ट बनाने की कल्पना कर सकते हैं। आपके द्वारा परिभाषित फ़ोल्डर के सभी उप फ़ोल्डर युक्त एक .pth फ़ाइल बनाने के लिए। क्या यह शायद स्टार्टअप पर चला है।


0

पुराने प्रश्न के लिए नया विकल्प। डेबियन पर पैकेज
स्थापित करना fail2ban, ऐसा लगता है कि यह /usr/lib/python3/dist-packages/fail2banपथ पर स्थापित करने के लिए हार्डकोड है न कि पायथन 3 पर sys.path


> python3
Python 3.7.3 (v3.7.3:ef4ec6ed12, Jun 25 2019, 18:51:50)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/usr/lib/python3.7/site-packages']
>>>

इसलिए, सिर्फ कॉपी करने के बजाय, मैंने (बैश) लाइब्रेरी को नए संस्करणों से जोड़ा।
मूल एप्लिकेशन को भविष्य के अपडेट, स्वचालित रूप से लिंक किए गए संस्करणों पर भी लागू होंगे।

 if [ -d /usr/lib/python3/dist-packages/fail2ban ]
   then
      for d in /usr/lib/python3.*
      do
         [ -d ${d}/fail2ban ] || \
            ln -vs /usr/lib/python3/dist-packages/fail2ban ${d}/
      done
   fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.