मैं एक फ़ाइल में एक वर्ग से विरासत में प्राप्त करना चाहता हूं जो कि वर्तमान में एक से ऊपर एक निर्देशिका में निहित है।
क्या उस फ़ाइल को अपेक्षाकृत आयात करना संभव है?
मैं एक फ़ाइल में एक वर्ग से विरासत में प्राप्त करना चाहता हूं जो कि वर्तमान में एक से ऊपर एक निर्देशिका में निहित है।
क्या उस फ़ाइल को अपेक्षाकृत आयात करना संभव है?
जवाबों:
from ..subpkg2 import mod
पायथन डॉक्स के अनुसार: जब पैकेज पदानुक्रम के अंदर होता है, तो दो डॉट्स का उपयोग करें, जैसा कि आयात विवरण डॉक्टर कहता है:
यह निर्दिष्ट करते समय कि मॉड्यूल को आयात करने के लिए आपको मॉड्यूल के पूर्ण नाम को निर्दिष्ट करने की आवश्यकता नहीं है। जब एक मॉड्यूल या पैकेज दूसरे पैकेज के भीतर निहित होता है, तो पैकेज नाम का उल्लेख किए बिना एक ही शीर्ष पैकेज के भीतर एक रिश्तेदार आयात करना संभव है। निर्दिष्ट मॉड्यूल या पैकेज में अग्रणी डॉट्स का उपयोग करने के बाद
from
आप निर्दिष्ट कर सकते हैं कि सटीक नामों को निर्दिष्ट किए बिना वर्तमान पैकेज पदानुक्रम को कैसे पार करना है। एक अग्रणी बिंदु का अर्थ है वर्तमान पैकेज जहां आयात करने वाला मॉड्यूल मौजूद है। दो डॉट्स का मतलब होता है एक पैकेज स्तर । तीन डॉट्स दो स्तरों पर है, आदि। यदि आप पैकेज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.
@ gimel का उत्तर सही है यदि आप उस पैकेज पदानुक्रम की गारंटी दे सकते हैं जिसका वह उल्लेख करता है। यदि आप नहीं कर सकते हैं - यदि आपकी वास्तविक जरूरत है जैसा कि आपने इसे व्यक्त किया है, विशेष रूप से निर्देशिकाओं से बंधा हुआ है और पैकेजिंग के लिए किसी भी आवश्यक संबंध के बिना - तो आपको __file__
मूल निर्देशिका ( os.path.dirname
कॉल की एक जोड़ी) करने के लिए काम करने की आवश्यकता होगी; -), तो (यदि वह निर्देशिका पहले से चालू नहीं है sys.path
) अस्थायी रूप से डालें sys.path
, के आरंभ में ही __import__
dir कहा जाता है, फिर से कहा dir को हटा दें - गन्दा काम वास्तव में, लेकिन, "जब आपको करना चाहिए," (और Pyhon steses प्रोग्रामर को कभी भी ऐसा करने से रोकना नहीं चाहिए जो किया जाना चाहिए - ठीक उसी तरह जैसे कि आईएसओ सी मानक अपने प्रस्तावना में "स्पिरिट ऑफ सी" सेक्शन में कहता है! -)।
यहाँ एक उदाहरण है जो आपके लिए काम कर सकता है:
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
इस प्रकार एक ही मॉड्यूल को विभिन्न नामों और सभी संबंधित बग के तहत उपलब्ध कराता है। autopath.py pypy या _preamble.py में ट्विस्ट किया गया, इसे एक खोज मापदंड का उपयोग करके हल करें जो निर्देशिकाओं को ऊपर की ओर ले जाते हुए शीर्ष-स्तरीय पैकेज की पहचान करता है।
sys.path.remove(pathYouJustAdded)
इस तरह के नए रास्ते को बनाए रखने के लिए जरूरी नहीं कि आयात के बाद आप कुछ करना चाहें ।
एक निर्देशिका से आयात मॉड्यूल जो वर्तमान निर्देशिका से ठीक एक स्तर ऊपर है:
from .. import module
from .. import module
मुझे त्रुटि मिली है मूल्य : सिफारिश का पालन करके गैर-पैकेज में संबंधित आयात का प्रयास किया गया
प्रस्तावना: मैंने अजगर के पारिस्थितिकी तंत्र में लोगों की आसानी से मदद करने की आशा के साथ पिछले उत्तर का पर्याप्त पुनर्लेखन किया, और उम्मीद है कि अजगर की आयात प्रणाली के साथ सभी को सफलता का सबसे अच्छा बदलाव दे।
यह एक पैकेज के भीतर रिश्तेदार आयात को कवर करेगा , जो मुझे लगता है कि ओपी के सवाल का सबसे संभावित मामला है।
यही कारण है कि हम लिखने के import 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
एक अजगर पैकेज आपके स्रोत कोड के बारे में जानकारी का एक संग्रह है, जो अन्य उपकरणों को सूचित कर सकता है कि आपके स्रोत कोड को अन्य कंप्यूटरों में कैसे कॉपी किया जाए, और अपने स्रोत कोड को उस सिस्टम के पथ में कैसे एकीकृत किया जाए ताकि import foo
अन्य कंप्यूटरों के लिए काम हो (दुभाषिया की परवाह किए बिना) होस्ट ऑपरेटिंग सिस्टम, आदि)
foo
कुछ निर्देशिका में अधिमानतः एक पैकेज का नाम है , (अधिमानतः एक खाली निर्देशिका)।
some_directory/
foo.py # `if __name__ == "__main__":` lives here
मेरी प्राथमिकता setup.py
सिबलिंग के रूप में बनाना है foo.py
, क्योंकि यह setup.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
फिर से फिर से इस निर्देशिका में स्रोत फ़ाइलों को लोड करने के लिए आयात करने वाली मशीनरी को पुनर्निर्देशित करेगा, बजाय मौजूदा सटीक फाइलों को इंस्टॉल-एनवायरनमेंट लाइब्रेरी में कॉपी करने के लिए। यह एक डेवलपर की मशीन पर व्यवहार संबंधी मतभेद भी पैदा कर सकता है, अपने कोड का परीक्षण करना सुनिश्चित करें! वहाँ पाइप के अलावा अन्य उपकरण हैं, हालांकि मैं सुझाव देता हूँ कि पाइप एक परिचयात्मक हो :)
मैं एक मॉड्यूल (एकल ".py" फ़ाइल) के बजाय foo
एक "पैकेज" (एक निर्देशिका युक्त __init__.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
, हालांकि हाइफ़न के लिए अंडरस्कोर को लोकप्रिय बनाना लोकप्रिय हैpython ./setup.py test
इसका बहुत विस्तार, यह भी मक्खी पर सी एक्सटेंशन संकलित कर सकता है अगर एक स्रोत मॉड्यूल एक विकास मशीन पर स्थापित किया जा रहा है। हर दिन के उदाहरण के लिए मैं PYPA नमूना रिपॉजिटरी के setup.py की सलाह देता हूं
यदि आप एक बिल्ड विरूपण साक्ष्य को जारी कर रहे हैं, उदाहरण के लिए कोड की एक प्रति जो लगभग समान कंप्यूटरों को चलाने के लिए है, तो एक आवश्यकताएँ। Txt फ़ाइल सटीक निर्भरता की जानकारी स्नैपशॉट के लिए एक लोकप्रिय तरीका है, जहां "install_requires" न्यूनतम कैप्चर करने का एक अच्छा तरीका है अधिकतम संगत संस्करण। हालांकि, यह देखते हुए कि लक्ष्य मशीनें वैसे भी लगभग समान हैं, मैं अत्यधिक एक पूरे अजगर उपसर्ग का टारबॉल बनाने की सलाह देता हूं। यह मुश्किल हो सकता है, यहां तक पहुंचने में बहुत विस्तृत है। की जाँच करें pip install
के --target
सुराग के लिए विकल्प, या virtualenv उर्फ venv।
उदाहरण के लिए वापस
Foo / spam / eggs.py से, अगर हम 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
।
अब किसी भी अजगर के संदर्भ से, हम अपने साझा py_modules और पैकेज लोड कर सकते हैं
#!/usr/bin/env python3
import bar
import foo
print(dir(bar))
print(dir(foo))
pip install --edit foo
, लगभग हमेशा एक वर्चुअन के अंदर। मैं लगभग एक मॉड्यूल को कभी नहीं लिखता हूं जिसे स्थापित करने का इरादा नहीं है। अगर मुझे कुछ गलत लगता है तो मैं जानना चाहूंगा।
editable
अंडे के लिंक और इंस्टॉल किए गए पायथन मॉड्यूल हर तरह से समान नहीं हैं; उदाहरण के लिए, एक संपादन योग्य मॉड्यूल में एक नया नाम स्थान जोड़ने से आपके पथ की खोज हो जाएगी, लेकिन अगर यह आपके सेटअप-थ्रू फ़ाइल में निर्यात नहीं होता है तो इसे पैक / स्थापित नहीं किया जाएगा! अपने उपयोग के मामले का परीक्षण करें :)