मैं अपने पूर्ण पथ को देखते हुए पायथन मॉड्यूल को कैसे लोड कर सकता हूं? ध्यान दें कि फ़ाइल फ़ाइल सिस्टम में कहीं भी हो सकती है, क्योंकि यह एक कॉन्फ़िगरेशन विकल्प है।
मैं अपने पूर्ण पथ को देखते हुए पायथन मॉड्यूल को कैसे लोड कर सकता हूं? ध्यान दें कि फ़ाइल फ़ाइल सिस्टम में कहीं भी हो सकती है, क्योंकि यह एक कॉन्फ़िगरेशन विकल्प है।
जवाबों:
पायथन 3.5+ उपयोग के लिए:
import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()
पायथन 3.3 और 3.4 उपयोग के लिए:
from importlib.machinery import SourceFileLoader
foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()
(हालांकि यह अजगर 3.4 में चित्रित किया गया है।)
पायथन 2 उपयोग के लिए:
import imp
foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()
संकलित पायथन फ़ाइलों और डीएलएल के लिए समान सुविधा कार्य हैं।
Http://bugs.python.org/issue21436 पर भी देखें ।
__import__
।
imp.load_source
केवल .__name__
दिए गए मॉड्यूल के पहले तर्क का मान सेट करता है। यह लोडिंग को प्रभावित नहीं करता है।
imp.load_source()
में बनाई गई नई प्रविष्टि की कुंजी का पहला तर्क निर्धारित करता है sys.modules
, इसलिए पहला तर्क वास्तव में लोडिंग को प्रभावित करता है।
imp
मॉड्यूल संस्करण 3.4 के बाद से हटा दिया गया है: imp
पैकेज के पक्ष में निंदा लंबित है importlib
।
Sys.path (imp का उपयोग करने से अधिक) के लिए एक पथ जोड़ने का लाभ यह है कि यह एकल पैकेज से एक से अधिक मॉड्यूल आयात करते समय चीजों को सरल करता है। उदाहरण के लिए:
import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')
from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch
sys.path.append
एक निर्देशिका के बजाय एक अजगर फ़ाइल को इंगित करने के लिए कैसे उपयोग करते हैं ?
importlib.import_module(mod_name)
यहां स्पष्ट आयात के बजाय इसका उपयोग किया जा सकता है यदि मॉड्यूल नाम रनटाइम पर ज्ञात नहीं है, तो मैं sys.path.pop()
अंत में एक जोड़ दूंगा , हालांकि, यह मानकर कि आयातित कोड अधिक मॉड्यूल आयात करने की कोशिश नहीं करता है क्योंकि इसका उपयोग किया जाता है।
यदि आपका शीर्ष-स्तरीय मॉड्यूल फ़ाइल नहीं है, लेकिन __init__.py के साथ निर्देशिका के रूप में पैक किया गया है, तो स्वीकृत समाधान लगभग काम करता है, लेकिन काफी नहीं। पायथन 3.5+ में निम्न कोड की आवश्यकता होती है (जोड़ा गया पंक्ति जो 'sys.modules' से शुरू होता है) पर ध्यान दें:
MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
इस पंक्ति के बिना, जब exec_module निष्पादित किया जाता है, तो यह आपके शीर्ष स्तर __init__.py में शीर्ष स्तर मॉड्यूल नाम के सापेक्ष आयात को बांधने की कोशिश करता है - इस मामले में "mymodule"। लेकिन "mymodule" को अभी तक लोड नहीं किया गया है, इसलिए आपको त्रुटि मिलेगी "SystemError: पैरेंट मॉड्यूल 'mymodule' लोड नहीं किया गया है, सापेक्ष आयात नहीं कर सकता है"। इसलिए आपको लोड करने से पहले नाम को बांधने की आवश्यकता है। इसका कारण सापेक्ष आयात प्रणाली का मूलभूत रूपांतर है: "अपरिवर्तनीय धारण यह है कि यदि आपके पास sys.modules ['स्पैम'] और sys.modules ['spam.foo'] (जैसा कि आप उपरोक्त आयात के बाद करेंगे) ), बाद वाले को पूर्व की foo विशेषता के रूप में प्रकट होना चाहिए " जैसा कि यहां चर्चा की गई है ।
mymodule
?
/path/to/your/module/
वास्तव में है /path/to/your/PACKAGE/
? और mymodule
तुम्हारा मतलब है myfile.py
?
अपने मॉड्यूल को आयात करने के लिए, आपको इसकी निर्देशिका को पर्यावरण चर में अस्थायी या स्थायी रूप से जोड़ना होगा।
import sys
sys.path.append("/path/to/my/modules/")
import my_module
अपनी .bashrc
फ़ाइल में (लाइनक्स में) निम्न लाइन जोड़कर source ~/.bashrc
टर्मिनल में प्रवेश करें:
export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"
क्रेडिट / स्रोत: saarrrr , एक और स्टैकएक्सचेंज प्रश्न
ऐसा लगता है कि आप विशेष रूप से कॉन्फ़िगरेशन फ़ाइल को आयात नहीं करना चाहते हैं (जिसमें कई साइड इफेक्ट्स और अतिरिक्त जटिलताएं शामिल हैं), आप बस इसे चलाना चाहते हैं, और परिणामी नामस्थान तक पहुंचने में सक्षम हो सकते हैं। मानक पुस्तकालय विशेष रूप से runpy.run_path के रूप में इसके लिए एक एपीआई प्रदान करता है :
from runpy import run_path
settings = run_path("/path/to/file.py")
वह इंटरफ़ेस Python 2.7 और Python 3.2+ में उपलब्ध है
result[name]
, result.get('name', default_value)
, आदि)
from runpy import run_path; from argparse import Namespace; mod = Namespace(**run_path('path/to/file.py'))
आप ऐसा कुछ भी कर सकते हैं और निर्देशिका को जोड़ सकते हैं कि कॉन्फ़िगरेशन फ़ाइल पायथन लोड पथ में बैठा है, और फिर बस एक सामान्य आयात करें, यह मानते हुए कि आप इस मामले में फ़ाइल का नाम पहले से जानते हैं, इस मामले में "कॉन्फ़िगरेशन"।
गन्दा, लेकिन यह काम करता है।
configfile = '~/config.py'
import os
import sys
sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
import config
def import_file(full_path_to_module):
try:
import os
module_dir, module_file = os.path.split(full_path_to_module)
module_name, module_ext = os.path.splitext(module_file)
save_cwd = os.getcwd()
os.chdir(module_dir)
module_obj = __import__(module_name)
module_obj.__file__ = full_path_to_module
globals()[module_name] = module_obj
os.chdir(save_cwd)
except:
raise ImportError
import_file('/home/somebody/somemodule.py')
except:
क्लॉज का उपयोग करना शायद ही कभी एक अच्छा विचार है।
save_cwd = os.getcwd()
try: …
finally: os.chdir(save_cwd)
this is already addressed by the standard library
हाँ, लेकिन अजगर को पिछड़े-संगत नहीं होने की आदत है ... जैसा कि उत्तर में कहा गया है कि 3.3 से पहले और बाद में 2 अलग-अलग तरीके हैं। उस मामले में, मैं नहीं बल्कि मक्खी पर चेक संस्करण की तुलना में अपने स्वयं के सार्वभौमिक कार्य लिखना चाहते हैं। और हाँ, शायद यह कोड बहुत अच्छी तरह से त्रुटि-सुरक्षित नहीं है, लेकिन यह एक विचार दिखाता है (जो कि os.chdir (), मैं हालांकि इसके बारे में नहीं है), जिसके आधार पर मैं एक बेहतर कोड लिख सकता हूं। इसलिए +1।
यहाँ कुछ कोड है जो 2.7-3.5 से और शायद अन्य लोगों से भी सभी पायथन संस्करणों में काम करता है।
config_file = "/tmp/config.py"
with open(config_file) as f:
code = compile(f.read(), config_file, 'exec')
exec(code, globals(), locals())
मैंने इसका परीक्षण किया। यह बदसूरत हो सकता है लेकिन अभी तक केवल एक ही है जो सभी संस्करणों में काम करता है।
load_source
ऐसा नहीं हुआ क्योंकि यह स्क्रिप्ट आयात करता है और आयात के समय मॉड्यूल और ग्लोबल्स को स्क्रिप्ट एक्सेस प्रदान करता है।
मैं @ सेबस्टियनरिटौ के अद्भुत उत्तर (पायथन> ३.४ के अनुसार) के थोड़े संशोधित संस्करण के साथ आया हूं, जो आपको spec_from_loader
इसके बजाय किसी मॉड्यूल के रूप में किसी भी एक्सटेंशन के साथ फाइल लोड करने की अनुमति देगा spec_from_file_location
:
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)
स्पष्ट रूप SourceFileLoader
से पथ को एन्कोडिंग करने का लाभ यह है कि मशीनरी एक्सटेंशन से फ़ाइल के प्रकार का पता लगाने की कोशिश नहीं करेगी। इसका मतलब है कि आप .txt
इस पद्धति का उपयोग करके किसी फ़ाइल की तरह कुछ लोड कर सकते हैं , लेकिन आप spec_from_file_location
लोडर को निर्दिष्ट किए बिना ऐसा नहीं कर सकते क्योंकि इसमें .txt
नहीं है importlib.machinery.SOURCE_SUFFIXES
।
क्या आपका मतलब लोड या इंपोर्ट है?
आप sys.path
सूची में हेरफेर कर सकते हैं अपने मॉड्यूल के लिए पथ निर्दिष्ट करें, फिर अपने मॉड्यूल को आयात करें। उदाहरण के लिए, यहां एक मॉड्यूल दिया गया है:
/foo/bar.py
तुम यह कर सकते थे:
import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar
sys.path[0:0] = ['/foo']
Explicit is better than implicit.
तो sys.path.insert(0, ...)
इसके बजाय क्यों नहीं sys.path[0:0]
?
मेरा मानना है कि आप निर्दिष्ट मॉड्यूल का उपयोग कर सकते हैं imp.find_module()
और imp.load_module()
लोड कर सकते हैं । आपको पथ के मॉड्यूल नाम को विभाजित करने की आवश्यकता होगी, अर्थात यदि आप लोड करना चाहते हैं तो आपको करना /home/mypath/mymodule.py
होगा:
imp.find_module('mymodule', '/home/mypath/')
... लेकिन वह काम पूरा होना चाहिए।
आप pkgutil
मॉड्यूल का उपयोग कर सकते हैं (विशेष रूप सेwalk_packages
वर्तमान निर्देशिका में संकुल की सूची प्राप्त करने के लिए विधि) का । वहां से importlib
आप जो मॉड्यूल चाहते हैं उसे आयात करने के लिए मशीनरी का उपयोग करना तुच्छ है :
import pkgutil
import importlib
packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
mod = importlib.import_module(name)
# do whatever you want with module now, it's been imported!
अजगर मॉड्यूल test.py बनाएँ
import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3
अजगर मॉड्यूल test_check.py बनाएं
from test import Client1
from test import Client2
from test import test3
हम आयातित मॉड्यूल को मॉड्यूल से आयात कर सकते हैं।
पायथन 3.4 का यह क्षेत्र समझने के लिए बेहद यातनापूर्ण लगता है! हालाँकि, एक शुरुआत के रूप में क्रिस कालोवे से कोड का उपयोग करके थोड़ी सी हैकिंग के साथ मैं कुछ काम पाने में कामयाब रहा। यहां मूल कार्य है।
def import_module_from_file(full_path_to_module):
"""
Import a module given the full path/filename of the .py file
Python 3.4
"""
module = None
try:
# Get module name and path from full path
module_dir, module_file = os.path.split(full_path_to_module)
module_name, module_ext = os.path.splitext(module_file)
# Get module "spec" from filename
spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)
module = spec.loader.load_module()
except Exception as ec:
# Simple error printing
# Insert "sophisticated" stuff here
print(ec)
finally:
return module
यह पायथन 3.4 से गैर-अपग्रेड किए गए मॉड्यूल का उपयोग करता प्रतीत होता है। मैं यह समझने का नाटक नहीं करता कि क्यों, लेकिन यह एक कार्यक्रम के भीतर से काम करने लगता है। मैंने पाया कि क्रिस का समाधान कमांड लाइन पर काम करता है, लेकिन एक कार्यक्रम के अंदर से नहीं।
मैं यह नहीं कह रहा हूं कि यह बेहतर है, लेकिन पूर्णता के लिए, मैं exec
फ़ंक्शन का सुझाव देना चाहता था , जो अजगर 2 और 3 दोनों में उपलब्ध है।
exec
आप वैश्विक दायरे में, या आंतरिक दायरे में मनमाने कोड को निष्पादित करने की अनुमति देते हैं, शब्दकोश के रूप में प्रदान किया गया।
उदाहरण के लिए, यदि आपके पास "/path/to/module
फ़ंक्शन के साथ " में एक मॉड्यूल संग्रहीत है foo()
, तो आप इसे निम्न कार्य करके चला सकते हैं:
module = dict()
with open("/path/to/module") as f:
exec(f.read(), module)
module['foo']()
इससे यह थोड़ा और स्पष्ट हो जाता है कि आप कोड को गतिशील रूप से लोड कर रहे हैं, और आपको कुछ अतिरिक्त शक्ति प्रदान करता है, जैसे कि कस्टम बिलिन प्रदान करने की क्षमता।
और यदि विशेषताओं के माध्यम से पहुंच हो, तो कुंजी के बजाय आपके लिए महत्वपूर्ण है, आप ग्लोबल्स के लिए एक कस्टम तानाशाह वर्ग को डिज़ाइन कर सकते हैं, जो इस तरह की पहुंच प्रदान करता है, जैसे:
class MyModuleClass(dict):
def __getattr__(self, name):
return self.__getitem__(name)
दिए गए फ़ाइलनाम से एक मॉड्यूल आयात करने के लिए, आप अस्थायी रूप से पथ का विस्तार कर सकते हैं, और अंत में ब्लॉक संदर्भ में सिस्टम पथ को पुनर्स्थापित कर सकते हैं :
filename = "directory/module.py"
directory, module_name = os.path.split(filename)
module_name = os.path.splitext(module_name)[0]
path = list(sys.path)
sys.path.insert(0, directory)
try:
module = __import__(module_name)
finally:
sys.path[:] = path # restore
यह काम करना चाहिए
path = os.path.join('./path/to/folder/with/py/files', '*.py')
for infile in glob.glob(path):
basename = os.path.basename(infile)
basename_without_extension = basename[:-3]
# http://docs.python.org/library/imp.html?highlight=imp#module-imp
imp.load_source(basename_without_extension, infile)
name, ext = os.path.splitext(os.path.basename(infile))
। आपका तरीका काम करता है क्योंकि पिछले .py एक्सटेंशन के लिए प्रतिबंध। साथ ही, आपको संभवतः मॉड्यूल को कुछ चर / शब्दकोश प्रविष्टि में आयात करना चाहिए।
अगर हमारे पास एक ही प्रोजेक्ट की स्क्रिप्ट्स हैं, लेकिन अलग-अलग डायरेक्टरी के साधनों में, हम इस समस्या को निम्न विधि से हल कर सकते हैं।
इस स्थिति utils.py
में हैsrc/main/util/
import sys
sys.path.append('./')
import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method
मैंने एक पैकेज बनाया है जो आपके imp
लिए उपयोग करता है। मैं इसे कॉल करता हूं import_file
और इसी तरह इसका उपयोग किया जाता है:
>>>from import_file import import_file
>>>mylib = import_file('c:\\mylib.py')
>>>another = import_file('relative_subdir/another.py')
आप इसे प्राप्त कर सकते हैं:
http://pypi.python.org/pypi/import_file
या कि
रनटाइम पर आयात पैकेज मॉड्यूल (पायथन नुस्खा)
http://code.activestate.com/recipes/223972/
###################
## #
## classloader.py #
## #
###################
import sys, types
def _get_mod(modulePath):
try:
aMod = sys.modules[modulePath]
if not isinstance(aMod, types.ModuleType):
raise KeyError
except KeyError:
# The last [''] is very important!
aMod = __import__(modulePath, globals(), locals(), [''])
sys.modules[modulePath] = aMod
return aMod
def _get_func(fullFuncName):
"""Retrieve a function object from a full dotted-package name."""
# Parse out the path, module, and function
lastDot = fullFuncName.rfind(u".")
funcName = fullFuncName[lastDot + 1:]
modPath = fullFuncName[:lastDot]
aMod = _get_mod(modPath)
aFunc = getattr(aMod, funcName)
# Assert that the function is a *callable* attribute.
assert callable(aFunc), u"%s is not callable." % fullFuncName
# Return a reference to the function itself,
# not the results of the function.
return aFunc
def _get_class(fullClassName, parentClass=None):
"""Load a module and retrieve a class (NOT an instance).
If the parentClass is supplied, className must be of parentClass
or a subclass of parentClass (or None is returned).
"""
aClass = _get_func(fullClassName)
# Assert that the class is a subclass of parentClass.
if parentClass is not None:
if not issubclass(aClass, parentClass):
raise TypeError(u"%s is not a subclass of %s" %
(fullClassName, parentClass))
# Return a reference to the class itself, not an instantiated object.
return aClass
######################
## Usage ##
######################
class StorageManager: pass
class StorageManagerMySQL(StorageManager): pass
def storage_object(aFullClassName, allOptions={}):
aStoreClass = _get_class(aFullClassName, StorageManager)
return aStoreClass(allOptions)
लिनक्स में, निर्देशिका में एक प्रतीकात्मक लिंक जोड़ने से आपकी अजगर स्क्रिप्ट स्थित है।
अर्थात:
ln -s /absolute/path/to/module/module.py /absolute/path/to/script/module.py
/absolute/path/to/script/module.pyc
यदि आप सामग्री बदलते हैं तो अजगर इसे बनाएगा और अपडेट करेगा/absolute/path/to/module/module.py
फिर mypythonscript.py में निम्नलिखित को शामिल करें
from module import *
git
और जाँच करके git status
देख सकते हैं कि स्क्रिप्ट में आपके परिवर्तन वास्तव में इसे स्रोत दस्तावेज़ में वापस ला रहे हैं और ईथर में खो नहीं रहे हैं।
मैंने importlib
मॉड्यूल के आधार पर अपना स्वयं का वैश्विक और पोर्टेबल आयात फ़ंक्शन लिखा है :
sys.path
या कभी खोज पथ संग्रहण पर निर्भर आयात आदेश को परिभाषित करने में सक्षम हो ।उदाहरण निर्देशिका संरचना:
<root>
|
+- test.py
|
+- testlib.py
|
+- /std1
| |
| +- testlib.std1.py
|
+- /std2
| |
| +- testlib.std2.py
|
+- /std3
|
+- testlib.std3.py
समावेश निर्भरता और व्यवस्था:
test.py
-> testlib.py
-> testlib.std1.py
-> testlib.std2.py
-> testlib.std3.py
कार्यान्वयन:
नवीनतम परिवर्तन की दुकान: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py
test.py :
import os, sys, inspect, copy
SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
SOURCE_DIR = os.path.dirname(SOURCE_FILE)
print("test::SOURCE_FILE: ", SOURCE_FILE)
# portable import to the global space
sys.path.append(TACKLELIB_ROOT) # TACKLELIB_ROOT - path to the library directory
import tacklelib as tkl
tkl.tkl_init(tkl)
# cleanup
del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
sys.path.pop()
tkl_import_module(SOURCE_DIR, 'testlib.py')
print(globals().keys())
testlib.base_test()
testlib.testlib_std1.std1_test()
testlib.testlib_std1.testlib_std2.std2_test()
#testlib.testlib.std3.std3_test() # does not reachable directly ...
getattr(globals()['testlib'], 'testlib.std3').std3_test() # ... but reachable through the `globals` + `getattr`
tkl_import_module(SOURCE_DIR, 'testlib.py', '.')
print(globals().keys())
base_test()
testlib_std1.std1_test()
testlib_std1.testlib_std2.std2_test()
#testlib.std3.std3_test() # does not reachable directly ...
globals()['testlib.std3'].std3_test() # ... but reachable through the `globals` + `getattr`
testlib.py :
# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)
print("1 testlib::SOURCE_FILE: ", SOURCE_FILE)
tkl_import_module(SOURCE_DIR + '/std1', 'testlib.std1.py', 'testlib_std1')
# SOURCE_DIR is restored here
print("2 testlib::SOURCE_FILE: ", SOURCE_FILE)
tkl_import_module(SOURCE_DIR + '/std3', 'testlib.std3.py')
print("3 testlib::SOURCE_FILE: ", SOURCE_FILE)
def base_test():
print('base_test')
testlib.std1.py :
# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)
print("testlib.std1::SOURCE_FILE: ", SOURCE_FILE)
tkl_import_module(SOURCE_DIR + '/../std2', 'testlib.std2.py', 'testlib_std2')
def std1_test():
print('std1_test')
testlib.std2.py :
# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)
print("testlib.std2::SOURCE_FILE: ", SOURCE_FILE)
def std2_test():
print('std2_test')
testlib.std3.py :
# optional for 3.4.x and higher
#import os, inspect
#
#SOURCE_FILE = os.path.abspath(inspect.getsourcefile(lambda:0)).replace('\\','/')
#SOURCE_DIR = os.path.dirname(SOURCE_FILE)
print("testlib.std3::SOURCE_FILE: ", SOURCE_FILE)
def std3_test():
print('std3_test')
आउटपुट ( 3.7.4
):
test::SOURCE_FILE: <root>/test01/test.py
import : <root>/test01/testlib.py as testlib -> []
1 testlib::SOURCE_FILE: <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE: <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE: <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE: <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE: <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib'])
base_test
std1_test
std2_test
std3_test
import : <root>/test01/testlib.py as . -> []
1 testlib::SOURCE_FILE: <root>/test01/testlib.py
import : <root>/test01/std1/testlib.std1.py as testlib_std1 -> ['testlib']
import : <root>/test01/std1/../std2/testlib.std2.py as testlib_std2 -> ['testlib', 'testlib_std1']
testlib.std2::SOURCE_FILE: <root>/test01/std1/../std2/testlib.std2.py
2 testlib::SOURCE_FILE: <root>/test01/testlib.py
import : <root>/test01/std3/testlib.std3.py as testlib.std3 -> ['testlib']
testlib.std3::SOURCE_FILE: <root>/test01/std3/testlib.std3.py
3 testlib::SOURCE_FILE: <root>/test01/testlib.py
dict_keys(['__name__', '__doc__', '__package__', '__loader__', '__spec__', '__annotations__', '__builtins__', '__file__', '__cached__', 'os', 'sys', 'inspect', 'copy', 'SOURCE_FILE', 'SOURCE_DIR', 'TackleGlobalImportModuleState', 'tkl_membercopy', 'tkl_merge_module', 'tkl_get_parent_imported_module_state', 'tkl_declare_global', 'tkl_import_module', 'TackleSourceModuleState', 'tkl_source_module', 'TackleLocalImportModuleState', 'testlib', 'testlib_std1', 'testlib.std3', 'base_test'])
base_test
std1_test
std2_test
std3_test
अजगर में परीक्षण किया गया 3.7.4
, 3.2.5
,2.7.16
पेशेवरों :
testlib.std.py
जैसे testlib
, testlib.blabla.py
जैसे testlib_blabla
और इतने पर)।sys.path
या कभी खोज पथ भंडारण पर निर्भर नहीं करता है ।SOURCE_FILE
और इसके SOURCE_DIR
बीच वैश्विक चर को बचाने / पुनर्स्थापित करने की आवश्यकता नहीं है tkl_import_module
।3.4.x
अधिक और अधिक के लिए] नेस्टेड tkl_import_module
कॉल (उदा: named->local->named
या) में मॉड्यूल नेमस्पेस को मिला सकते हैंlocal->named->local
तो)।3.4.x
और उच्चतर] वैश्विक चर / कार्यों / कक्षाओं को निर्यात कर सकता है जहां से tkl_import_module
( tkl_declare_global
फ़ंक्शन के माध्यम से ) आयात किए गए सभी बच्चों के मॉड्यूल के लिए घोषित किया जा रहा है ।विपक्ष :
3.3.x
और कम] tkl_import_module
सभी मॉड्यूल में घोषणा करने की आवश्यकता है जो tkl_import_module
(कोड दोहराव) को कॉल करता हैअपडेट 1,2 (के लिए)3.4.x
केवल और अधिक)
पायथन 3.4 और उच्चतर में आप tkl_import_module
प्रत्येक मॉड्यूल को घोषित करने की आवश्यकता को बायपास कर सकते हैंtkl_import_module
को एक शीर्ष स्तर के मॉड्यूल और फ़ंक्शन एक ही कॉल में सभी बच्चों के मॉड्यूल को इंजेक्ट करेगा (यह एक प्रकार का स्वयं तैनात आयात है)।
अपडेट ३ :
आयात पर समर्थन निष्पादन गार्ड के साथ tkl_source_module
बैश करने के लिए एनालॉग के रूप में जोड़ा गया समारोह source
(आयात के बजाय मॉड्यूल मर्ज के माध्यम से कार्यान्वित)।
अपडेट 4 :
tkl_declare_global
ऑटो फ़ंक्शन को सभी बच्चों के मॉड्यूल में एक मॉड्यूल वैश्विक चर निर्यात करने के लिए जोड़ा गया है जहां एक मॉड्यूल वैश्विक चर दिखाई नहीं दे रहा है क्योंकि बाल मॉड्यूल का हिस्सा नहीं है।
अद्यतन ५ :
सभी फ़ंक्शन टैकलिब लाइब्रेरी में चले गए हैं, ऊपर दिए गए लिंक को देखें।
एक पैकेज है जो विशेष रूप से इसके लिए समर्पित है:
from thesmuggler import smuggle
# À la `import weapons`
weapons = smuggle('weapons.py')
# À la `from contraband import drugs, alcohol`
drugs, alcohol = smuggle('drugs', 'alcohol', source='contraband.py')
# À la `from contraband import drugs as dope, alcohol as booze`
dope, booze = smuggle('drugs', 'alcohol', source='contraband.py')
यह पायथन संस्करणों (ज्योन और पायपी) में भी परीक्षण किया गया है, लेकिन यह आपके प्रोजेक्ट के आकार के आधार पर ओवरकिल हो सकता है।
उत्तर की सूची में इसे जोड़ने से मुझे कुछ भी काम नहीं मिला। यह 3.4 में संकलित (pyd) पायथन मॉड्यूल के आयात की अनुमति देगा:
import sys
import importlib.machinery
def load_module(name, filename):
# If the Loader finds the module name in this list it will use
# module_name.__file__ instead so we need to delete it here
if name in sys.modules:
del sys.modules[name]
loader = importlib.machinery.ExtensionFileLoader(name, filename)
module = loader.load_module()
locals()[name] = module
globals()[name] = module
load_module('something', r'C:\Path\To\something.pyd')
something.do_something()
काफी सरल तरीका: मान लीजिए कि आप सापेक्ष पथ के साथ फ़ाइल आयात करना चाहते हैं ..//MyLibs/pyfunc.py
libPath = '../../MyLibs'
import sys
if not libPath in sys.path: sys.path.append(libPath)
import pyfunc as pf
लेकिन अगर आप इसे बिना किसी गार्ड के बनाते हैं तो आपको आखिरकार बहुत लंबा रास्ता मिल सकता है
पैकेज के importlib
बजाय एक सरल समाधान imp
(पायथन 2.7 के लिए परीक्षण किया गया, हालांकि यह पायथन 3 के लिए भी काम करना चाहिए):
import importlib
dirname, basename = os.path.split(pyfilepath) # pyfilepath: '/my/path/mymodule.py'
sys.path.append(dirname) # only directories should be added to PYTHONPATH
module_name = os.path.splitext(basename)[0] # '/my/path/mymodule.py' --> 'mymodule'
module = importlib.import_module(module_name) # name space of defined module (otherwise we would literally look for "module_name")
अब आप सीधे इस तरह आयातित मॉड्यूल के नाम स्थान का उपयोग कर सकते हैं:
a = module.myvar
b = module.myfunc(a)
इस समाधान का लाभ यह है कि हमारे कोड में इसका उपयोग करने के लिए हमें उस मॉड्यूल का वास्तविक नाम जानने की आवश्यकता नहीं है जिसे हम आयात करना चाहते हैं । यह उपयोगी है, उदाहरण के लिए, यदि मॉड्यूल का पथ एक विन्यास योग्य तर्क है।
sys.path
, जो हर उपयोग के मामले में फिट नहीं है।
sys.path.pop()
यह उत्तर सेबेस्टियन रिताऊ के जवाब का एक पूरक है जो टिप्पणी का जवाब देता है: "लेकिन क्या होगा यदि आपके पास मॉड्यूल का नाम नहीं है?" यह एक त्वरित और गंदा तरीका है, जिसे संभवतया पायथन मॉड्यूल नाम दिया गया है, जिसे एक फ़ाइल नाम दिया गया है - यह केवल पेड़ तक जाता है जब तक कि यह एक __init__.py
फ़ाइल के बिना एक निर्देशिका नहीं पाता है और फिर इसे फ़ाइल नाम में बदल देता है। पायथन 3.4+ के लिए (पाथलिब का उपयोग करता है), जो समझ में आता है क्योंकि Py2 लोग "imp" या अन्य तरीकों के सापेक्ष उपयोग कर सकते हैं:
import pathlib
def likely_python_module(filename):
'''
Given a filename or Path, return the "likely" python module name. That is, iterate
the parent directories until it doesn't contain an __init__.py file.
:rtype: str
'''
p = pathlib.Path(filename).resolve()
paths = []
if p.name != '__init__.py':
paths.append(p.stem)
while True:
p = p.parent
if not p:
break
if not p.is_dir():
break
inits = [f for f in p.iterdir() if f.name == '__init__.py']
if not inits:
break
paths.append(p.stem)
return '.'.join(reversed(paths))
सुधार के लिए निश्चित रूप से संभावनाएं हैं, और वैकल्पिक __init__.py
फ़ाइलों को अन्य परिवर्तनों की आवश्यकता हो सकती है, लेकिन यदि आपके पास __init__.py
सामान्य है, तो यह चाल है।
सबसे अच्छा तरीका, मुझे लगता है, आधिकारिक दस्तावेज से है ( 29.1। Imp - आयात इंटर्ल्स तक पहुँच ):
import imp
import sys
def __import__(name, globals=None, locals=None, fromlist=None):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass
# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.
fp, pathname, description = imp.find_module(name)
try:
return imp.load_module(name, fp, pathname, description)
finally:
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()