আমি বর্তমানের উপরের একটি ডিরেক্টরিতে থাকা একটি ফাইলের একটি শ্রেণীর কাছ থেকে উত্তরাধিকারী হতে চাই।
অপেক্ষাকৃত ফাইলটি কি আমদানি করা সম্ভব?
আমি বর্তমানের উপরের একটি ডিরেক্টরিতে থাকা একটি ফাইলের একটি শ্রেণীর কাছ থেকে উত্তরাধিকারী হতে চাই।
অপেক্ষাকৃত ফাইলটি কি আমদানি করা সম্ভব?
উত্তর:
from ..subpkg2 import mod
পাইথন ডক্স অনুসারে: যখন প্যাকেজ শ্রেণিবিন্যাসের ভিতরে থাকে তখন দুটি বিন্দু ব্যবহার করুন, যেমন আমদানি বিবৃতি ডক বলে:
কোন মডিউলটি আমদানি করতে হবে তা নির্দিষ্ট করার সময় আপনাকে মডিউলটির পরম নাম উল্লেখ করতে হবে না। যখন কোনও মডিউল বা প্যাকেজ অন্য প্যাকেজের মধ্যে থাকে তখন প্যাকেজের নাম উল্লেখ না করে একই শীর্ষ প্যাকেজের মধ্যে একটি আপেক্ষিক আমদানি করা সম্ভব। নির্দিষ্ট মডিউল বা প্যাকেজটিতে শীর্ষস্থানীয় বিন্দু ব্যবহার করে
from
আপনি নির্দিষ্ট নামগুলি উল্লেখ না করে বর্তমান প্যাকেজ শ্রেণিবিন্যাসকে কতটা উচ্চতর করতে হবে তা নির্দিষ্ট করতে পারেন। একটি শীর্ষস্থানীয় ডট মানে বর্তমান প্যাকেজ যেখানে আমদানি করা মডিউলটি বিদ্যমান। দুটি বিন্দু মানে একটি প্যাকেজ স্তর । তিনটি বিন্দু দুটি স্তরের উপরে থাকে ইত্যাদি So তাই আপনি যদি প্যাকেজেরfrom . import mod
কোনও মডিউল থেকে চালনা করেনpkg
তবে আপনার আমদানি শেষ হবেpkg.mod
। আপনি যদি এরfrom ..subpkg2 import mod
মধ্যে থেকে নির্বাহ করেনpkg.subpkg1
তবে আমদানি করবেনpkg.subpkg2.mod
। আপেক্ষিক আমদানির জন্য স্পেসিফিকেশন পিইপি 328 এর মধ্যে রয়েছে ।
পিইপি 328 সম্পূর্ণ / আপেক্ষিক আমদানির বিষয়ে ডিল করে।
import sys
sys.path.append("..") # Adds higher directory to python modules path.
@ জিমেলের উত্তরটি সঠিক যদি আপনি প্যাকেজ শ্রেণিবিন্যাসের উল্লেখ করেছেন তবে। যদি আপনি না করতে পারেন - যদি আপনার আসল প্রয়োজনটি যেমনটি আপনি প্রকাশ করেছেন তেমনই হয়, কেবল ডিরেক্টরিতে আবদ্ধ এবং প্যাকেজিংয়ের সাথে কোনও প্রয়োজনীয় সম্পর্ক ছাড়াই - তবে আপনাকে __file__
প্যারেন্ট ডিরেক্টরিটি খুঁজে বের করার জন্য কাজ করতে হবে (কয়েকবার os.path.dirname
কল করবে; -), তারপর (যদি ডিরেক্টরিটি ইতিমধ্যেই নয় sys.path
) শুরুতে যোগ অস্থায়ীভাবে সন্নিবেশ খুব শুরুতে Dir বলেন sys.path
, __import__
, অপসারণ আবার Dir বলেন - নোংরা কাজ প্রকৃতপক্ষে, কিন্তু, "আপনি যখন অবশ্যই, আপনাকে অবশ্যই" (এবং Pyhon কঠোর পরিশ্রম করে করতে প্রোগ্রামারকে যা করা উচিত তা করা থেকে কখনই থামান না - ঠিক যেমন আইএসও সি স্ট্যান্ডার্ড তার উপস্থায় "স্পিরিট অফ সি" বিভাগে বলেছে! -)।
এখানে একটি উদাহরণ যা আপনার জন্য কাজ করতে পারে:
import sys
import os.path
sys.path.append(
os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))
import module_in_parent_dir
sys.path
একই নামটি বিভিন্ন নাম এবং সমস্ত সম্পর্কিত বাগের আওতায় পাওয়া যায়। পাইপিতে অটোপ্যাথ.পি বা প্যাঁচে _preamble.py ডিরেক্টরিগুলি উপরের দিকে ট্র্যাভার করার সময় শীর্ষ স্তরের প্যাকেজ সনাক্তকারী অনুসন্ধান মানদণ্ড ব্যবহার করে এটি সমাধান করুন।
sys.path.remove(pathYouJustAdded)
নতুন আমদানি করার পরে এমন কিছু করতে চাইবেন যাতে এই নতুন পথটি ধরে রাখা যায় না।
একটি ডিরেক্টরি থেকে আমদানি করুন মডিউল যা বর্তমান ডিরেক্টরি থেকে এক স্তর মাত্র:
from .. import module
from .. import module
আমি ব্যবহার করে ত্রুটি পেয়েছি ভ্যালু এরির: প্রস্তাবনাটি অনুসরণ করে নন-প্যাকেজে আপেক্ষিক আমদানির চেষ্টা করা হয়েছে
উপস্থাপনা: আমি পাইথনের ইকোসিস্টেমগুলিতে লোকেদের স্বাচ্ছন্দ্যে সাহায্য করার আশায় পূর্বের উত্তরের একটি উল্লেখযোগ্য পুনর্লিখন করেছি এবং আশা করি সবাইকে পাইথনের আমদানি ব্যবস্থায় সফলতার সেরা পরিবর্তন উপহার দিয়েছি।
এটি কোনও প্যাকেজের মধ্যে আপেক্ষিক আমদানি কভার করবে , যা আমি মনে করি ওপির প্রশ্নের সবচেয়ে সম্ভাব্য কেস।
এই কারণেই আমরা লেখার import foo
পরিবর্তে মূল নামের স্থান থেকে একটি মডিউল "foo" লোড করতে লিখি:
foo = dict(); # please avoid doing this
with open(os.path.join(os.path.dirname(__file__), '../foo.py') as foo_fh: # please avoid doing this
exec(compile(foo_fh.read(), 'foo.py', 'exec'), foo) # please avoid doing this
এই কারণেই আমরা পরিবেশে পাইথন এম্বেড করতে পারি যেখানে জাইথনের মতো ভার্চুয়াল সরবরাহ না করে কোনও ডিফাক্টো ফাইল সিস্টেম নেই।
একটি ফাইল সিস্টেম থেকে ডিউলড হওয়ার কারণে আমদানিগুলি নমনীয় হতে দেয়, এই নকশাটি সংরক্ষণাগার / জিপ ফাইলগুলি থেকে আমদানি, সিঙ্গেলনগুলি, বাইটকোড ক্যাচিং, সিএফআই এক্সটেনশানগুলি, এমনকি রিমোট কোড সংজ্ঞা লোডিংয়ের মতো জিনিসগুলির জন্য অনুমতি দেয়।
সুতরাং যদি আমদানিগুলি কোনও ফাইল সিস্টেমে সংযুক্ত না হয় তবে "একটি ডিরেক্টরি আপ" এর অর্থ কী? আমাদের কিছু হিউরিস্টিকস বাছাই করতে হবে তবে আমরা এটি করতে পারি, উদাহরণস্বরূপ প্যাকেজের মধ্যে কাজ করার সময় , কিছু হিউরিস্টিকস ইতিমধ্যে সংজ্ঞায়িত করা হয়েছে যা একই প্যাকেজের মধ্যে আপেক্ষিক আমদানিকে পছন্দ করে .foo
এবং..foo
কাজ করে। শান্ত!
যদি আপনি আন্তরিকভাবে কোনও ফাইল সিস্টেমে আপনার উত্স কোড লোডিং প্যাটার্নগুলি জোড়া দিতে চান তবে আপনি এটি করতে পারেন। আপনাকে নিজের হিউরিস্টিকস নির্বাচন করতে হবে এবং একধরণের আমদানি যন্ত্রপাতি ব্যবহার করতে হবে, আমি আমদানি সুপারিশ করব
পাইথনের ইম্পোর্টলিব উদাহরণটি এরকম কিছু দেখায়:
import importlib.util
import sys
# For illustrative purposes.
file_path = os.path.join(os.path.dirname(__file__), '../foo.py')
module_name = 'foo'
foo_spec = importlib.util.spec_from_file_location(module_name, file_path)
# foo_spec is a ModuleSpec specifying a SourceFileLoader
foo_module = importlib.util.module_from_spec(foo_spec)
sys.modules[module_name] = foo_module
foo_spec.loader.exec_module(foo_module)
foo = sys.modules[module_name]
# foo is the sys.modules['foo'] singleton
সরকারীভাবে এখানে একটি দুর্দান্ত উদাহরণ প্রকল্প পাওয়া যায়: https://github.com/pypa/sampleproject ject
পাইথন প্যাকেজটি হ'ল আপনার উত্স কোড সম্পর্কিত তথ্যের সংকলন, যা অন্য সরঞ্জামগুলিকে কীভাবে আপনার উত্স কোডটি অন্য কম্পিউটারে অনুলিপি করতে পারে এবং কীভাবে আপনার উত্স কোডটিকে সেই সিস্টেমের পথে সংহত করতে পারে যাতে import foo
অন্যান্য কম্পিউটারের জন্য কাজ করে (দোভাষী, নির্বিশেষে, হোস্ট অপারেটিং সিস্টেম, ইত্যাদি)
foo
কিছু ডিরেক্টরিতে (পছন্দমতো খালি ডিরেক্টরি) প্যাকেজের নাম দেওয়া যাক ।
some_directory/
foo.py # `if __name__ == "__main__":` lives here
আমার পছন্দটি হ'ল setup.py
ভাইবোন হিসাবে তৈরি করা foo.py
, কারণ এটি সেটআপ.পি ফাইলটি সহজ করে লেখাকে সহজ করে তোলে, তবে আপনি যদি পছন্দ করেন তবে ডিফল্টরূপে সেটআপলগুলি যা কিছু করে সেটআপলুলগুলি পুনর্নির্দেশ করতে কনফিগারেশন লিখতে পারেন; উদাহরণস্বরূপ, foo.py
"src /" ডিরেক্টরিতে অন্তর্ভুক্ত করা কিছুটা জনপ্রিয়, এখানে আচ্ছাদিত নয়।
some_directory/
foo.py
setup.py
।
#!/usr/bin/env python3
# setup.py
import setuptools
setuptools.setup(
name="foo",
...
py_modules=['foo'],
)
।
python3 -m pip install --editable ./ # or path/to/some_directory/
"সম্পাদনযোগ্য" ওরফে -e
ইনস্টল-পরিবেশের লাইব্রেরিতে বর্তমান সঠিক ফাইলগুলি অনুলিপি করার পরিবর্তে, এই ডিরেক্টরিতে উত্স ফাইলগুলি লোড করতে আমদানি করা যন্ত্রপাতিটিকে পুনর্নির্দেশ করবে। এটি কোনও বিকাশকারীর মেশিনে আচরণগত পার্থক্যের কারণও হতে পারে, আপনার কোডটি পরীক্ষা করে নিশ্চিত হন! পাইপ ব্যতীত অন্য সরঞ্জাম রয়েছে, তবে আমি পাইপটিকে পরিচয় করিয়ে দেওয়ার পরামর্শ দিই :)
আমি মডিউলের পরিবর্তে foo
একটি "প্যাকেজ" (একটি ডিরেক্টরি সম্বলিত ডিরেক্টরি __init__.py
) তৈরি করতে চাই (একটি একক ".py" ফাইল), উভয় "প্যাকেজ" এবং "মডিউল" রুট নেমস্পেসে লোড করা যায়, মডিউলগুলি নেস্টেড নেমস্পেসের জন্য অনুমতি দেয়, আমরা যদি "আপেক্ষিক একটি ডিরেক্টরি আপ" আমদানি করতে চাই তবে এটি সহায়ক।
some_directory/
foo/
__init__.py
setup.py
।
#!/usr/bin/env python3
# setup.py
import setuptools
setuptools.setup(
name="foo",
...
packages=['foo'],
)
আমি একটি করতে চান foo/__main__.py
, এই একটি মডিউল রূপে প্যাকেজ চালানো পাইথন, যেমন পারবেন python3 -m foo
চালানো হবে foo/__main__.py
যেমন __main__
।
some_directory/
foo/
__init__.py
__main__.py # `if __name__ == "__main__":` lives here, `def main():` too!
setup.py
।
#!/usr/bin/env python3
# setup.py
import setuptools
setuptools.setup(
name="foo",
...
packages=['foo'],
...
entry_points={
'console_scripts': [
# "foo" will be added to the installing-environment's text mode shell, eg `bash -c foo`
'foo=foo.__main__:main',
]
},
)
এটিকে আরও কিছু মডিউল দিয়ে বেরিয়ে আসতে দেয়: মূলত, আপনার মতো ডিরেক্টরি কাঠামো থাকতে পারে:
some_directory/
bar.py # `import bar`
foo/
__init__.py # `import foo`
__main__.py
baz.py # `import foo.baz
spam/
__init__.py # `import foo.spam`
eggs.py # `import foo.spam.eggs`
setup.py
setup.py
প্রচলিতভাবে উত্স কোড সম্পর্কে মেটাডেটার তথ্য ধারণ করে যেমন:
foo
, যদিও হাইফেনগুলির জন্য আন্ডারস্কোর স্থাপন করা জনপ্রিয় thoughpython ./setup.py test
এটি খুব বিস্তৃত, এটি কোনও উত্সের মডিউল কোনও ডেভলপমেন্ট মেশিনে ইনস্টল করা থাকলে ফ্লাইতে সি এক্সটেনশানগুলি সংকলন করতে পারে। প্রতিদিনের উদাহরণের জন্য আমি পিওয়াইপিএ নমুনা সংগ্রহস্থলের সেটআপ.পিপি সুপারিশ করি
যদি আপনি একটি বিল্ড আর্টিক্ট প্রকাশ করে থাকেন, উদাহরণস্বরূপ কোডের একটি অনুলিপি যা প্রায় অভিন্ন কম্পিউটার চালানোর জন্য বোঝানো হয় তবে একটি প্রয়োজনীয়তা.txt ফাইল হুবহু নির্ভরতা সম্পর্কিত তথ্য স্ন্যাপশটের একটি জনপ্রিয় উপায়, যেখানে "ইনস্টল_রেইকায়ারস" ন্যূনতম এবং ক্যাপচার করার একটি ভাল উপায় where সর্বাধিক সামঞ্জস্যপূর্ণ সংস্করণ। যাইহোক, লক্ষ্য মেশিনগুলি যাইহোক যাইহোক প্রায় অভিন্ন, আমি অত্যন্ত অজগর উপসর্গের একটি টারবাল তৈরি করার পরামর্শ দিচ্ছি। এটি এখানে প্রবেশের জন্য খুব জটিল, খুব বিশদ হতে পারে। পরীক্ষা করে দেখুন pip install
এর --target
বিশালাকার জন্য বিকল্প, অথবা virtualenv ওরফে venv।
উদাহরণ ফিরে
Foo / স্প্যাম / ডিম.পি থেকে, যদি আমরা foo / baz এর কোড চাইতাম তবে আমরা এর নিখুঁত নেমস্পেসের মাধ্যমে এটি জানতে চাইতে পারি:
import foo.baz
আমরা যদি ভবিষ্যতে অন্য কিছু আপেক্ষিক baz
বাস্তবায়নের মাধ্যমে ডিম.পি.কে অন্য কোনও ডিরেক্টরিতে স্থানান্তরিত করার ক্ষমতা সংরক্ষণ করতে চাই , আমরা আপেক্ষিক আমদানি যেমন ব্যবহার করতে পারি:
import ..baz
পাইথন কোডটি নির্ভরযোগ্যভাবে লোড করতে, সেই কোডটি একটি মডিউলে এবং সেই মডিউলটি পাইথনের লাইব্রেরিতে ইনস্টল করা থাকে।
ইনস্টল করা মডিউলগুলি সর্বদা শীর্ষ স্তরের নেমস্পেসের সাথে লোড করা যায় import <name>
সরকারীভাবে এখানে একটি দুর্দান্ত নমুনা প্রকল্প উপলব্ধ: https://github.com/pypa/sampleproject
মূলত, আপনার যেমন ডিরেক্টরি কাঠামো থাকতে পারে:
the_foo_project/
setup.py
bar.py # `import bar`
foo/
__init__.py # `import foo`
baz.py # `import foo.baz`
faz/ # `import foo.faz`
__init__.py
daz.py # `import foo.faz.daz` ... etc.
।
আপনার setuptools.setup()
মধ্যে ঘোষণা করতে ভুলবেন না setup.py
,
সরকারী উদাহরণ: https://github.com/pypa/sampleproject/blob/master/setup.py
আমাদের ক্ষেত্রে আমরা সম্ভবত রফতানি করতে চাই bar.py
এবং foo/__init__.py
আমার সংক্ষিপ্ত উদাহরণ:
#!/usr/bin/env python3
import setuptools
setuptools.setup(
...
py_modules=['bar'],
packages=['foo'],
...
entry_points={},
# Note, any changes to your setup.py, like adding to `packages`, or
# changing `entry_points` will require the module to be reinstalled;
# `python3 -m pip install --upgrade --editable ./the_foo_project
)
।
পাইথন লাইব্রেরিতে এখন আমরা আমাদের মডিউলটি ইনস্টল করতে পারি; পাইপের সাহায্যে the_foo_project
আপনি সম্পাদনা মোডে আপনার অজগর লাইব্রেরিতে ইনস্টল করতে পারেন , তাই আমরা এটি রিয়েল টাইমে কাজ করতে পারি
python3 -m pip install --editable=./the_foo_project
# if you get a permission error, you can always use
# `pip ... --user` to install in your user python library
।
এখন যে কোনও অজগর প্রসঙ্গ থেকে আমরা আমাদের ভাগ করা পাইওয়াই মডেলগুলি এবং প্যাকেজগুলি লোড করতে পারি
#!/usr/bin/env python3
import bar
import foo
print(dir(bar))
print(dir(foo))
pip install --edit foo
প্রায়শই কোনও ভার্চুয়ালেনভের অভ্যন্তরে কাজ করার সময় আমার মডিউলটি ইনস্টল করি । আমি প্রায় কোনও মডিউল লিখি না যা ইনস্টল করার উদ্দেশ্যে নয়। আমি যদি কিছু ভুল বুঝি তবে আমি জানতে চাই।
editable
ডিমের লিঙ্ক এবং ইনস্টলড পাইথন মডিউলগুলি প্রতিটি উপায়ে একেবারে একরকম হয় না তেমন সহায়ক ; উদাহরণস্বরূপ, একটি সম্পাদনযোগ্য মডিউলে একটি নতুন নেমস্পেস যুক্ত করা আপনার পাথ লুকে দেখতে পাওয়া যাবে, তবে এটি যদি আপনার সেটআপ.পি ফাইলে রফতানি না হয় তবে এটি প্যাকেজ / ইনস্টল হবে না! আপনার ব্যবহারের