अगर अजगर मॉड्यूल आयात किया गया है तो कैसे जांचें?


93

यदि मैं कोड में कहीं मॉड्यूल का आयात करता हूं तो मैं कैसे जांच करूं?

 if not has_imported("somemodule"):
     print('you have not imported somemodule')

कारण यह है कि अगर मैं पहले से ही एक मॉड्यूल आयात करता हूं, तो मैं यह जांचना चाहता हूं कि मेरे पास एक मॉड्यूल है जिसे मैं आयात नहीं करना चाहता हूं क्योंकि कभी-कभी यह मेरे कार्यक्रम को गड़बड़ कर देता है।


जिस raise SystemError()मॉड्यूल को आप आयात नहीं करना चाहते, उसके शीर्ष पर बस (या अपनी पसंद का अन्य अपवाद) रखें। यदि आप करते हैं वास्तव में यह कहीं आयात करते हैं, अपने कार्यक्रम ट्रैसबैक और बाहर निकलने फेंक देते हैं।
लार्क्स

वैसे भी किसी मॉड्यूल को आयात करना आपके कार्यक्रम को कैसे भी गड़बड़ कर सकता है? इतनी संभावना नहीं है।
बिल वुडगेर


@MartijnPieters Yoiks। और आयात इतना तटस्थ लगता है।
बिल वुडगेर

जवाबों:


126

sys.modulesशब्दकोश में मॉड्यूल नाम के लिए परीक्षण :

import sys

modulename = 'datetime'
if modulename not in sys.modules:
    print 'You have not imported the {} module'.format(modulename)

डोक्यूमेंटेशन से:

यह एक ऐसा शब्दकोश है जो मॉड्यूल नामों को उन मॉड्यूलों में मैप करता है जो पहले ही लोड किए जा चुके हैं।

ध्यान दें कि एक importकथन दो काम करता है:

  1. यदि मॉड्यूल को पहले कभी आयात नहीं किया गया है (== मौजूद नहीं है sys.modules), तो इसे लोड किया गया है और इसमें जोड़ा गया है sys.modules
  2. वर्तमान नेमस्पेस में 1 या अधिक नामों को बांधें जो मॉड्यूल ऑब्जेक्ट या उन ऑब्जेक्ट्स का संदर्भ देते हैं जो मॉड्यूल नेमस्पेस के सदस्य हैं।

modulename not in sys.modulesयदि चरण 1 पर अभिव्यक्ति अभिव्यक्ति हुई है। चरण 2 के परिणाम के परीक्षण के लिए यह जानना आवश्यक है कि importविभिन्न वस्तुओं को संदर्भित करने के लिए विभिन्न नामों को निर्धारित करने के लिए क्या सटीक कथन का उपयोग किया गया था:

  • import modulename सेट modulename = sys.modules['modulename']
  • import packagename.nestedmoduleसेट packagename = sys.modules['packagename'](कोई भी अतिरिक्त स्तर जो आप जोड़ते हैं)
  • import modulename as altname सेट altname = sys.module['modulename']
  • import packagename.nestedmodule as altname सेट altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname सेट objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulenameसेट nestedmodulename = sys.modules['packagename.nestedmodulename'](केवल जब इस आयात से पहले नाम स्थान nestedmodulenameमें कोई ऑब्जेक्ट नाम नहीं था packagename, नेस्टेड मॉड्यूल के लिए एक अतिरिक्त नाम इस बिंदु पर मूल पैकेज नामस्थान में जोड़ा गया है)
  • from somemodule import objectname as altname सेट altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altnameसेट altname = sys.modules['packagename.nestedmodulename'](केवल जब इस आयात से पहले नाम स्थान nestedmodulenameमें कोई ऑब्जेक्ट नाम नहीं था packagename, नेस्टेड मॉड्यूल के लिए एक अतिरिक्त नाम इस बिंदु पर मूल पैकेज नामस्थान में जोड़ा गया है)

आप परीक्षण कर सकते हैं कि जिस नाम से आयातित वस्तु बंधी थी, वह किसी दिए गए नामस्थान में मौजूद है:

# is this name visible in the current scope:
'importedname' in dir()

# or, is this a name in the globals of the current module:
'importedname' in globals()

# or, does the name exist in the namespace of another module:
'importedname' in globals(sys.modules['somemodule'])

यह केवल आपको बताता है कि नाम मौजूद है (बाध्य किया गया है), न कि यदि यह उस मॉड्यूल से किसी विशिष्ट मॉड्यूल या ऑब्जेक्ट को संदर्भित करता है। आप उस वस्तु या परीक्षण को आगे बढ़ा सकते हैं यदि यह वही वस्तु है जो इसमें उपलब्ध है sys.modules, यदि आपको यह बताने की आवश्यकता है कि नाम तब से पूरी तरह से किसी और चीज़ पर सेट किया गया है।


1
क्या यह एक फ़ंक्शन के अंदर एक आवश्यक पैकेज की जांच करने का सबसे अच्छा तरीका है? अर्थात्, मान लें कि कुछ फ़ंक्शन के लिए numpyपैकेज की आवश्यकता है - import sysफ़ंक्शन के अंदर का उपयोग यह जांचने के लिए सबसे अच्छा है कि इसे आयात किया गया है? "सर्वश्रेष्ठ" से मेरा मतलब है कि प्रदर्शन प्रभाव की अवधि, जैसा import sysकि तब होगा जब हर बार फ़ंक्शन को बुलाया जाता है। धन्यवाद
चकित

@ अगर आप चिंता करते हैं तो आप फ़ंक्शन के बाहर sys आयात कर सकते हैं। ऐसा नहीं है कि import sysकिसी भी तरह से महंगा है; sysहमेशा मौजूद है, यह डिफ़ॉल्ट रूप से पहले से लोड है। लेकिन एक वैकल्पिक पैकेज के लिए: बस पैकेज आयात करें । पकड़ो ImportErrorअपवाद अगर पैकेज स्थापित नहीं है, और एक ध्वज का संकेत यह स्थापित किया गया है जब आयात सफल होता है निर्धारित किया है। उसके बाद आप वैकल्पिक निर्भरता के अपने उपयोग को सूचित करने के लिए ध्वज का उपयोग कर सकते हैं।
मार्टिन पीटर्स

@Confounded name in sys.modulesयदि आप आयात नहीं करना चाहते हैं तो परीक्षण केवल उपयोगी है ।
मार्टिन पीटर्स

26

स्वीकार किए गए sys.modules के उत्तर के लिए, मैं आयात पर मॉड्यूल का नाम बदलने के बारे में सावधान रहने के लिए एक चेतावनी जोड़ूंगा:

>>> import sys
>>> import datetime as dt
>>> 'dt' in sys.modules
False
>>> 'datetime' in sys.modules
True

18

एक मॉड्यूल आयात किया गया है, तो परीक्षण करने के लिए sys.modules का उपयोग करें (मैं एक उदाहरण के रूप में यूनिकोडेटा का उपयोग कर रहा हूं):

>>> import sys
>>> 'unicodedata' in sys.modules
False
>>> import unicodedata
>>> 'unicodedata' in sys.modules
True

5

sys.modules दुभाषिया के वर्तमान उदाहरण में कहीं भी उपयोग किए जाने वाले सभी मॉड्यूल शामिल हैं और यदि किसी अन्य पायथन मॉड्यूल में आयात किया गया है तो यह दिखाता है।

dir() जाँच करता है कि क्या नाम वर्तमान नामस्थान में परिभाषित किया गया था।

2 का संयोजन प्रत्येक अलग से अधिक सुरक्षित है और जब तक आप copyखुद को परिभाषित नहीं करते हैं तब तक काम करता है ।

if ('copy' in sys.modules) and ('copy' in dir()):

0
if "sys" not in dir():
  print("sys not imported!")

यह केवल जाँचता है कि क्या मॉड्यूल को वर्तमान नामस्थान में आयात किया गया था। इसके अलावा sysकुछ भी हो सकता है, न कि केवल एक मॉड्यूल।
तिजोरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.