পাইথন মডিউলটির পুরো পথটি রেখে আমি কীভাবে লোড করতে পারি? নোট করুন যে ফাইলটি সিস্টেম সিস্টেমের যে কোনও জায়গায় থাকতে পারে, কারণ এটি একটি কনফিগারেশন বিকল্প।
পাইথন মডিউলটির পুরো পথটি রেখে আমি কীভাবে লোড করতে পারি? নোট করুন যে ফাইলটি সিস্টেম সিস্টেমের যে কোনও জায়গায় থাকতে পারে, কারণ এটি একটি কনফিগারেশন বিকল্প।
উত্তর:
পাইথন 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()
(যদিও এটি পাইথন ৩.৪-এ অবহেলা করা হয়েছে।)
পাইথন 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__
ফেরত মডিউলের সেট করে sets এটি লোডিং প্রভাবিত করে না।
imp.load_source()
তৈরি হওয়া নতুন এন্ট্রিটির কী নির্ধারণ করে sys.modules
, তাই প্রথম যুক্তিটি প্রকৃতপক্ষে লোডকে প্রভাবিত করে।
imp
মডিউল সংস্করণ 3.4 থেকে অবচিত হয়: imp
প্যাকেজ পক্ষে থামিয়ে দেওয়া মুলতুবি আছে importlib
।
Sys.path- এ কোনও পাথ যুক্ত করার সুবিধা (ইমপ ব্যবহারের মাধ্যমে) একক প্যাকেজ থেকে একাধিক মডিউল আমদানি করার সময় জিনিসগুলি সহজতর করে। উদাহরণ স্বরূপ:
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 দিয়ে ডিরেক্টরি হিসাবে প্যাকেজ করা থাকে তবে গ্রহণযোগ্য সমাধানটি প্রায় কাজ করে তবে বেশ কার্যকর নয়। পাইথনে ৩.৫+-তে নিম্নলিখিত কোডের প্রয়োজন হয় ('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)
এই লাইনটি ছাড়াই, যখন এক্সিকিউটিড: মডিউলটি কার্যকর করা হয়, এটি আপনার শীর্ষ স্তরের __init__.py শীর্ষ স্তরের মডিউল নামটিতে আপেক্ষিক আমদানিকে আবদ্ধ করার চেষ্টা করে - এই ক্ষেত্রে "মাইমডিউল"। তবে "মাইমডিউল" এখনও লোড করা যায় নি তাই আপনি ত্রুটিটি পেয়ে যাবেন "সিস্টেমেরর: পিতামাতা মডিউল 'মায়োমডিউল' লোড হয়নি, আপেক্ষিক আমদানি সম্পাদন করতে পারে না"। সুতরাং নামটি লোড করার আগে আপনাকে নামটি আবদ্ধ করতে হবে। এর কারণ আপেক্ষিক আমদানি ব্যবস্থার মৌলিক আগ্রাসন: "আক্রমণকারী হোল্ডিংটি হ'ল যদি আপনার 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/"
ক্রেডিট / উত্স: স্যারার , অন্য স্ট্যাকেক্সচেঞ্জ প্রশ্ন
দেখে মনে হচ্ছে আপনি কনফিগারেশন ফাইলটি বিশেষভাবে আমদানি করতে চান না (যার পুরো পার্শ্ব প্রতিক্রিয়া এবং এতে জড়িত অতিরিক্ত জটিলতা রয়েছে), আপনি কেবল এটি চালনা করতে চান, এবং ফলস্বরূপ নামের স্থানটি অ্যাক্সেস করতে সক্ষম হবেন। স্ট্যান্ডার্ড লাইব্রেরি বিশেষত এটির জন্য একটি এপিআই সরবরাহ করে যা runpy.run_path আকারে :
from runpy import run_path
settings = run_path("/path/to/file.py")
পাইথন ২.7 এবং পাইথন ৩.২+ এ এই ইন্টারফেসটি উপলব্ধ
result[name]
, result.get('name', default_value)
ইত্যাদি)
from runpy import run_path; from argparse import Namespace; mod = Namespace(**run_path('path/to/file.py'))
আপনি এটির মতোও কিছু করতে পারেন এবং পাইথন লোডের পথে কনফিগারেশন ফাইলটি যে ডিরেক্টরিটি বসে আছে সেই ডিরেক্টরিটি যুক্ত করতে পারেন এবং তারপরে "কনফিগারেশন" হিসাবে এই ফাইলটির নাম আগে থেকেই জানেন ass
অগোছালো তবে এটি কাজ করে।
configfile = '~/config.py'
import os
import sys
sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
import config
imp.load_dynamic(module_name, path_to_file)
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
হ্যাঁ, তবে পাইথনের পশ্চাৎপদ-সামঞ্জস্যপূর্ণ না হওয়ার অভ্যাস রয়েছে ... যাচাই করা উত্তরে বলা হয়েছে যে ৩.৩ এর আগে ও পরে দুটি ভিন্ন উপায় রয়েছে। সেক্ষেত্রে আমি ফ্লাইতে চেক সংস্করণের চেয়ে নিজের ইউনিভার্সাল ফাংশনটি লিখতে চাই। এবং হ্যাঁ, সম্ভবত এই কোডটি খুব ভাল ত্রুটি-সুরক্ষিত নয়, তবে এটি একটি ধারণা দেখায় (যা os.chdir (), এটি সম্পর্কে আমার কিছু জানা নেই), যার ভিত্তিতে আমি আরও ভাল কোড লিখতে পারি। সুতরাং +1।
এখানে কিছু কোড যা সমস্ত পাইথন সংস্করণে কাজ করে, ২.7-৩.৫ এবং সম্ভবত অন্যগুলি থেকে।
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!
পাইথন মডিউল টেস্ট.পি তৈরি করুন
import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3
পাইথন মডিউল টেস্ট_চেক.পি তৈরি করুন
from test import Client1
from test import Client2
from test import test3
আমরা মডিউল থেকে আমদানি করা মডিউলটি আমদানি করতে পারি।
পাইথনের এই অঞ্চলটি ৩.৪ বোঝার জন্য অত্যন্ত মারাত্মক বলে মনে হচ্ছে! তবে ক্রিস কল্লোয়ের কাছ থেকে কোড শুরু করে কিছুটা হ্যাকিং দিয়ে শুরু করে আমি কিছু কাজ করতে সক্ষম হয়েছি। এখানে বেসিক ফাংশন।
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
এটি পাইথন ৩.৪ থেকে অবহিত মডিউলগুলি ব্যবহার করে বলে মনে হচ্ছে। আমি কেন তা বোঝার ভান করি না, তবে মনে হয় এটি কোনও প্রোগ্রামের মধ্যে থেকেই কাজ করবে। আমি ক্রিসের সমাধানটি কমান্ড লাইনে কাজ করে দেখলাম তবে কোনও প্রোগ্রামের অভ্যন্তরে নয়।
আমি বলছি না এটি আরও ভাল, তবে সম্পূর্ণতার জন্য, আমি 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
তারপরে মাইপাইথনস্ক্রিপ্ট.পি-তে নিম্নলিখিতগুলি অন্তর্ভুক্ত করুন
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
পরীক্ষা.পি :
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`
টেস্টলিব.পি :
# 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
শুধুমাত্র এবং এর জন্য উচ্চতর):
পাইথন ৩.৪ এবং উচ্চতর ক্ষেত্রে আপনি একটি শীর্ষ স্তরের মডিউল ঘোষণা tkl_import_module
করে প্রতিটি মডিউলটিতে ঘোষণার প্রয়োজনীয়তাটি বাইপাস করতে পারেন tkl_import_module
এবং ফাংশনটি একটি শিশুকে সমস্ত শিশু মডিউলগুলিতে নিজেই ইনজেক্ট করবে (এটি একধরনের স্ব-আমদানি আমদানি)।
আপডেট 3 :
আমদানির উপর সাপোর্ট এক্সিকিউশন গার্ডের সাথে tkl_source_module
বাশকে অ্যানালগ হিসাবে ফাংশন যুক্ত করা হয়েছে source
(আমদানির পরিবর্তে মডিউল মেশিনের মাধ্যমে প্রয়োগ করা হয়)।
আপডেট 4 :
tkl_declare_global
সমস্ত শিশু মডিউলগুলিতে একটি মডিউল গ্লোবাল ভেরিয়েবল স্বয়ংক্রিয়ভাবে রফতানি করার জন্য যুক্ত ফাংশন যুক্ত করা হয়েছে যেখানে কোনও মডিউল গ্লোবাল ভেরিয়েবল দৃশ্যমান নয় কারণ কোনও শিশু মডিউলের অংশ নয়।
আপডেট 5 :
সমস্ত ফাংশন ট্যাকললিব লাইব্রেরিতে চলে গেছে, উপরের লিঙ্কটি দেখুন।
এখানে একটি প্যাকেজ রয়েছে যা এটি বিশেষভাবে উত্সর্গীকৃত:
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 এ সংকলিত (পাইড) পাইথন মডিউলগুলি আমদানির অনুমতি দেবে:
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
(পাইথন ২.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
ফাইল ছাড়াই ডিরেক্টরি খুঁজে না পায় এবং তারপরে এটিকে ফাইলের নামে রূপান্তরিত করে না। পাইথন ৩.৪++ এর জন্য (প্যাথলিব ব্যবহার করে), যেহেতু পাই 2 লোকেরা "ইমপ" বা আপেক্ষিক আমদানি করার অন্যান্য উপায় ব্যবহার করতে পারে:
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
files চ্ছিক ফাইলগুলি অন্যান্য পরিবর্তনের প্রয়োজন হতে পারে তবে আপনার __init__.py
যদি সাধারণভাবে থাকে তবে এটি কৌশলটি কার্যকর করে।
আমার মনে হয়, সর্বোত্তম উপায়টি অফিশিয়াল ডকুমেন্টেশন থেকে রয়েছে ( ২৯.১। ইম্প। - আমদানির অভ্যন্তরীণ প্রবেশাধিকার ):
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()