python - एक सापेक्ष पथ से एक मॉड्यूल आयात करें




relative-path python-import (15)

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

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

ln -s (path)/module_name.py

या

ln -s (path)/package_name

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

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

मैं अपने सापेक्ष पथ को दिए गए पायथन मॉड्यूल को कैसे आयात करूं?

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

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

dirFoo\
    Foo.py
    dirBar\
        Bar.py

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


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

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

# 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)

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

  1. निर्देशिका स्क्रिप्ट (या वर्तमान निर्देशिका) युक्त निर्देशिका।
  2. पायथनपैथ (निर्देशिका नामों की एक सूची, उसी वाक्यविन्यास के साथ खोल परिवर्तनीय पथ)।
  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']

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

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

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

from .dirBar import Bar

अगर मैं नाम की जगह बार की तरह दिखाना चाहता था। जो कुछ भी , या

from . import dirBar

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


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

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

lib/abc.py

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

__init__.py

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

from lib.abc import <Your Module name>

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


एक और समाधान py-require पैकेज स्थापित करना होगा और फिर Foo.py में निम्न का उपयोग करना Foo.py

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

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

उदाहरण:

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

कोड:

from Desktop.test import *

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


मानक पुस्तकालय से pkgutil मॉड्यूल को देखो। यह आपको जो भी चाहिए वो करने में मदद कर सकता है।


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

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!")

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


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

from dirBar.Bar import *

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


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

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

विशेष रूप से, डीआईआरएफयू का मानना ​​है कि डायरबार से एक निर्देशिका है ...

DirFoo \ Foo.py में:

from ..dirBar import Bar

यह मानते हुए कि आपकी दोनों निर्देशिका असली पायथन पैकेज हैं (उनके अंदर __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 फ़ाइल के अंदर है। यह शायद भी विफल रहता है।


सापेक्ष 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

this उत्तर के आधार पर।


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


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

import mymodule




python-import