यह जांचने के लिए कि कोई अजगर मॉड्यूल बिना आयात किए मौजूद है या नहीं


179

मुझे यह जानने की जरूरत है कि क्या एक पायथन मॉड्यूल मौजूद है, बिना आयात किए।

ऐसा कुछ आयात करना जो अस्तित्व में न हो (जो मैं चाहता हूं):

try:
    import eggs
except ImportError:
    pass

4
मैं उत्सुक हूं, आयात का उपयोग करने के लिए डाउनसाइड क्या हैं?
चक

15
यदि आपके मॉड्यूल के साइड इफेक्ट्स हैं, तो कॉलिंग आयात के अवांछित परिणाम हो सकते हैं। इसलिए, यदि आप जांच करना चाहते हैं कि किसी फ़ाइल के किस संस्करण को पहले चलाना है, तो आप नीचे दिए गए उत्तर के साथ जांच कर सकते हैं, और बाद में आयात कर सकते हैं। मैं सुझाव नहीं दे रहा हूं कि साइड इफेक्ट्स के साथ मॉड्यूल लिखना एक अच्छा विचार है - लेकिन हम सभी वयस्क हैं और अपने खुद के निर्णय ले सकते हैं कि हम कितने खतरनाक तरीके से कोड करना चाहते हैं।
यरबेलक


1
@ArtOfWarfare मैंने अभी-अभी उस प्रश्न को बंद किया है जो आपने इस एक के डुप्लिकेट के रूप में जोड़ा है । क्योंकि यह प्रश्न स्पष्ट है और यहाँ प्रस्तावित समाधान भी वहाँ सूचीबद्ध अन्य सभी की तुलना में बेहतर है। मैं इसके बजाय जो कोई भी इस बेहतर समाधान का जवाब चाहता है वह लोगों को इससे दूर जाने की ओर इशारा करता है।
बकुरीउ

7
@ इसके अलावा मॉड्यूल मौजूद हो सकता है, लेकिन स्वयं में आयात त्रुटियां हो सकती हैं। आयात कोड को ऊपर दिए गए कोड के रूप में पकड़ने से मॉड्यूल को इंगित करने के लिए नेतृत्व हो सकता है, जब तथ्य यह होता है लेकिन इसमें त्रुटियां नहीं होती हैं।
माइकल बार्टन

जवाबों:


199

को Python2

यह जांचने के लिए कि क्या आयात python2 में कुछ पा सकता है, का उपयोग कर imp

import imp
try:
    imp.find_module('eggs')
    found = True
except ImportError:
    found = False

बिंदीदार आयात खोजने के लिए, आपको और अधिक करने की आवश्यकता है:

import imp
try:
    spam_info = imp.find_module('spam')
    spam = imp.load_module('spam', *spam_info)
    imp.find_module('eggs', spam.__path__) # __path__ is already a list
    found = True
except ImportError:
    found = False

आप pkgutil.find_loaderpython3 भाग के समान (कम या ज्यादा) का उपयोग कर सकते हैं

import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None

python3

पायथन 3। 3.3

आप का उपयोग करना चाहिए importlib, मैं यह करने के बारे में कैसे गया था:

import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None

मेरी उम्मीद की जा रही है, अगर आप इसके लिए लोडर पा सकते हैं, तो यह मौजूद है। आप इसके बारे में थोड़ा और अधिक स्मार्ट हो सकते हैं, जैसे कि फ़िल्टर करना कि आप किस लोडर को स्वीकार करेंगे। उदाहरण के लिए:

import importlib
spam_loader = importlib.find_loader('spam')
# only accept it as valid if there is a source file for the module - no bytecode only.
found = issubclass(type(spam_loader), importlib.machinery.SourceFileLoader)

पायथन 3 on 3.4

Python3.4 में importlib.find_loader अजगर डॉक्स के पक्ष में पदावनत किया गया था importlib.util.find_spec। अनुशंसित विधि है importlib.util.find_spec। ऐसे अन्य लोग हैं importlib.machinery.FileFinder, जो लोड करने के लिए एक विशिष्ट फ़ाइल के बाद उपयोगी होते हैं। उनका उपयोग कैसे करना है, इसका पता लगाना इस के दायरे से बाहर है।

import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None

यह भी रिश्तेदार आयात के साथ काम करता है लेकिन आपको शुरुआती पैकेज की आपूर्ति करनी चाहिए, इसलिए आप यह भी कर सकते हैं:

import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"

हालांकि मुझे यकीन है कि ऐसा करने के लिए एक कारण मौजूद है - मुझे यकीन नहीं है कि यह क्या होगा।

चेतावनी

एक सबमॉड्यूल खोजने की कोशिश करते समय, यह मूल मॉड्यूल आयात करेगा ( उपरोक्त सभी विधियों के लिए)!

food/
  |- __init__.py
  |- eggs.py

## __init__.py
print("module food loaded")

## eggs.py
print("module eggs")

were you then to run
>>> import importlib
>>> spam_spec = importlib.find_spec("food.eggs")
module food loaded
ModuleSpec(name='food.eggs', loader=<_frozen_importlib.SourceFileLoader object at 0x10221df28>, origin='/home/user/food/eggs.py')

टिप्पणियाँ इस के आसपास होने पर स्वागत करते हैं

स्वीकृतियाँ

  • @ आयात के लिए
  • @ लुतास-गाइडो के लिए python3.3 + depricating find_loader
  • python2.7 में pkgutils.find_loader व्यवहार के लिए @enpenax

3
यह केवल शीर्ष-स्तरीय मॉड्यूल के लिए काम करता है, के लिए नहीं eggs.ham.spam
हेमफ्लिट

3
@hemflit अगर आप ढूंढना चाहते हैं spamमें eggs.hamआप का प्रयोग करेंगेimp.find_module('spam', ['eggs', 'ham'])
gitaarik

5
+1, लेकिन impहै पदावनत के पक्ष में importlib3. अजगर में
rvighne

4
क्या होगा यदि आयातित मॉड्यूल में एक वास्तविक "ImportError" है। यही मेरे साथ हो रहा था। फिर मॉड्यूल मौजूद है लेकिन "पाया" नहीं जाएगा।
enpenax

1
एक साल बाद मैं उसी समस्या के सामने आया जिसका मैंने ऊपर उल्लेख किया था और पायथन 2 के समाधान के लिए खुदाई कर रहा था: pkgutil.find_loader("my.package.module")यदि पैकेज / मॉड्यूल मौजूद है और Noneनहीं तो लोडर लौटाता है । कृपया अपने जवाब को पायथन 2 के लिए अपडेट कर दें, क्योंकि
आयात करने के लिए मास्क

13

यारबेलक की प्रतिक्रिया का उपयोग करने के बाद, मैंने इसे आयात करने के लिए नहीं बनाया है ìmp

try:
    __import__('imp').find_module('eggs')
    # Make things with supposed existing module
except ImportError:
    pass

settings.pyउदाहरण के लिए Django में उपयोगी है ।


4
मैंने डाउनवोट किया, क्योंकि यह मास्क मॉड्यूल में त्रुटियों को आयात करता है, जो त्रुटि को स्पॉट करने के लिए वास्तव में कठिन बनाता है।
एनपेक्सैक्स

1
डाउनवोट एक बुरा विचार है, एक अच्छी बात यह है कि "हमेशा लॉग की गई त्रुटियों को लॉग करें"। यह लिखने के बाद एक उदाहरण है कि आप इसे कैसे चाहते हैं।
ज़ुलु

2
यदि आयातित मॉड्यूल लाइन 1 पर एक आयात के साथ विफल रहता है और आपकी कोशिश पकड़ को विफल कर देती है तो आप एक त्रुटि कैसे दर्ज करेंगे?
एनपेनैक्स

मैं सिर्फ वास्तविक जीवन में मास्किंग-आयात-त्रुटियों के मुद्दे में चला गया हूं, और यह खराब था (परीक्षण के कारण जो पास होना चाहिए था!)।
डेविड

मैं उस जगह भाग गया, जहां कोई उस त्रुटि का उपयोग करके एक अलग मॉड्यूल पर एक बंदरों को ट्रिगर कर रहा था ... जो कि खोजने के लिए पागलपन था
yarbelk

13

पायथन 3> = 3.6: मॉड्यूलनोटफाउंडर्र

ModuleNotFoundErrorमें शुरू किया गया है अजगर 3.6 और इस उद्देश्य के लिए इस्तेमाल किया जा सकता

try:
    import eggs
except ModuleNotFoundError:
    # Error handling
    pass

जब कोई मॉड्यूल या उसके माता-पिता में से कोई भी नहीं मिल सकता है, तो त्रुटि उठाई जाती है । इसलिए

try:
    import eggs.sub
except ModuleNotFoundError as err:
    # Error handling
    print(err)

एक संदेश मुद्रित करेगा जो ऐसा दिखता है जैसे No module named 'eggs'कि eggsमॉड्यूल नहीं मिल सकता है; लेकिन कुछ ऐसा प्रिंट करेगा जैसे No module named 'eggs.sub'कि केवल subमॉड्यूल नहीं मिल सकता है लेकिन eggsपैकेज मिल सकता है।

पर अधिक जानकारी के लिए आयात प्रणाली के प्रलेखन देखेंModuleNotFoundError


1
यह हिरण सवाल का जवाब नहीं है क्योंकि यह पैकेज का आयात करता है यदि वह मौजूद है
divenex

11

पायथ्रॉन 2, इम्पोर्टइयर के भरोसे के बिना

जब तक वर्तमान उत्तर अपडेट नहीं किया जाता है, तब तक यहां पायथन 2 के लिए रास्ता है

import pkgutil
import importlib

if pkgutil.find_loader(mod) is not None:
    return importlib.import_module(mod)
return None

दूसरा जवाब क्यों?

बहुत सारे जवाब एक को पकड़ने का उपयोग करते हैं ImportError। इसके साथ समस्या यह है, कि हम यह नहीं जान सकते कि क्या फेंकता है ImportError

यदि आप अपने अस्तित्व के मॉड्यूल को आयात करते हैं और ImportErrorआपके मॉड्यूल में एक होना होता है (जैसे लाइन 1 पर टाइपो), तो परिणाम यह होगा कि आपका मॉड्यूल मौजूद नहीं है। यह आपको यह पता लगाने के लिए काफी मात्रा में ले जाएगा कि आपका मॉड्यूल मौजूद है और ImportErrorपकड़ा गया है और चीजों को चुपचाप विफल करता है।


यह अस्पष्ट हो सकता है, लेकिन सभी लेकिन पहले कोड ब्लॉक पर भरोसा नहीं करते हैं ImportError- कृपया इसे संपादित करें यदि यह आपके लिए अस्पष्ट था।
यरबेलक

मैं आपको पहले दो पायथन 2 उदाहरणों में ImportError कैच का उपयोग करते हुए देखता हूं। फिर वे वहां क्यों हैं?
एनपेनैक्स

3
यह आयात आयात करता है अगर mod == 'not_existing_package.mymodule'। नीचे
मार्सिन रेज़्स्की

1
बेशक यह एक आयात त्रुटि फेंकता है। यदि कोई मॉड्यूल मौजूद नहीं है, तो इसे आयात त्रुटि फेंकना चाहिए। इस तरह से आप इसे ज़रूरत पड़ने पर पकड़ सकते हैं। अन्य समाधानों के साथ समस्या यह है कि वे अन्य त्रुटियों का सामना करते हैं।
एनपेनैक्स

कोशिश करें / छोड़कर का मतलब यह नहीं है कि आपको लॉग इन या चीजों को सुनिश्चित नहीं करना चाहिए। आप किसी भी अंतर्निहित ट्रेसबैक को पूरी तरह से पकड़ सकते हैं और कुछ भी कर सकते हैं जिसे आप चाहते हैं।
ज़ुलु

8

एक लाइनर के रूप में go_as का उत्तर

 python -c "help('modules');" | grep module

6

इस प्रश्न के उत्तर में मैं यह जांचने का तरीका खोज रहा था कि क्या मॉड्यूल को कमांड लाइन से लोड किया गया है और मेरे बाद आने वाले लोगों के लिए अपने विचार साझा करना चाहते हैं और उसी की तलाश कर रहे हैं:

Linux / UNIX स्क्रिप्ट फ़ाइल विधि : एक फ़ाइल बनाएँ module_help.py:

#!/usr/bin/env python

help('modules')

फिर सुनिश्चित करें कि यह निष्पादन योग्य है: chmod u+x module_help.py

और एक से कॉल करने pipeके लिए grep:

./module_help.py | grep module_name

अंतर्निहित मदद प्रणाली को लागू करें । (यह फ़ंक्शन इंटरैक्टिव उपयोग के लिए अभिप्रेत है ।) यदि कोई तर्क नहीं दिया जाता है, तो इंटरप्रेटर कंसोल पर इंटरैक्टिव मदद प्रणाली शुरू होती है। यदि तर्क एक स्ट्रिंग है , तो स्ट्रिंग को एक मॉड्यूल , फ़ंक्शन, वर्ग, विधि, कीवर्ड या प्रलेखन विषय के नाम के रूप में देखा जाता है , और कंसोल पर एक सहायता पृष्ठ मुद्रित होता है। यदि तर्क किसी अन्य प्रकार की वस्तु है, तो ऑब्जेक्ट पर एक सहायता पृष्ठ उत्पन्न होता है।

इंटरएक्टिव विधि : कंसोल लोड मेंpython

>>> help('module_name')

यदि टाइप करके पढ़ना छोड़ दिया जाए q
तो पायथन इंटरएक्टिव सेशन से बाहर निकलें Ctrl+D

विंडोज स्क्रिप्ट फ़ाइल विधि भी लिनक्स / यूनिक्स संगत, और बेहतर समग्र :

#!/usr/bin/env python

import sys

help(sys.argv[1])

कमांड से इसे कॉल करना जैसे:

python module_help.py site  

उत्पादन होगा:

मॉड्यूल साइट पर मदद:

NAME साइट - तीसरे पक्ष के पैकेज के लिए मॉड्यूल खोज पथ को sys.path में जोड़ें।

FILE /usr/lib/python2.7/site.py

MODULE DOCS http://docs.python.org/library/site

DESCRIPTION
...
:

और आपको qइंटरेक्टिव मोड से बाहर निकलने के लिए प्रेस करना होगा ।

इसका उपयोग अज्ञात मॉड्यूल:

python module_help.py lkajshdflkahsodf

उत्पादन होगा:

'lkajshdflkahsodf' के लिए कोई पायथन प्रलेखन नहीं मिला

और बाहर निकलें।


5

उदाहरण के लिए, pkgutil के किसी एक कार्य का उपयोग करें :

from pkgutil import iter_modules

def module_exists(module_name):
    return module_name in (name for loader, name, ispkg in iter_modules())

5

एक सरल अगर AskUbuntu से बयान: मैं कैसे जाँचता हूं कि क्या पायथन में एक मॉड्यूल स्थापित है?

import sys
print('eggs' in sys.modules)

4
यह केवल परीक्षण करता है कि क्या यह स्थापित है, न कि यह इंस्टॉल करने योग्य है।
डेविड

4

आप बस एक छोटी सी स्क्रिप्ट लिख सकते हैं जो सभी मॉड्यूलों को आयात करने की कोशिश करेगी और आपको बताएगी कि कौन से लोग असफल हो रहे हैं और कौन से काम कर रहे हैं:

import pip


if __name__ == '__main__':
    for package in pip.get_installed_distributions():
        pack_string = str(package).split(" ")[0]
        try:
            if __import__(pack_string.lower()):
                print(pack_string + " loaded successfully")
        except Exception as e:
            print(pack_string + " failed with error code: {}".format(e))

आउटपुट:

zope.interface loaded successfully
zope.deprecation loaded successfully
yarg loaded successfully
xlrd loaded successfully
WMI loaded successfully
Werkzeug loaded successfully
WebOb loaded successfully
virtualenv loaded successfully
...

चेतावनी का शब्द यह सब कुछ आयात करने की कोशिश करेगा ताकि आप चीजों को देखेंगे PyYAML failed with error code: No module named pyyamlक्योंकि वास्तविक आयात नाम सिर्फ yaml है। इसलिए जब तक आप अपने आयात को जानते हैं यह आपके लिए चाल चलनी चाहिए।


3

मैंने यह सहायक कार्य लिखा है:

def is_module_available(module_name):
    if sys.version_info < (3, 0):
        # python 2
        import importlib
        torch_loader = importlib.find_loader(module_name)
    elif sys.version_info <= (3, 3):
        # python 3.0 to 3.3
        import pkgutil
        torch_loader = pkgutil.find_loader(module_name)
    elif sys.version_info >= (3, 4):
        # python 3.4 and above
        import importlib
        torch_loader = importlib.util.find_spec(module_name)

    return torch_loader is not None

2

आप importlibसीधे भी उपयोग कर सकते हैं

import importlib

try:
    importlib.import_module(module_name)
except ImportError:
    # Handle error

यह वास्तव में इसे आयात करने की समस्या है। साइड इफेक्ट्स और सभी
yarbelk

2

यदि "डॉटेड मॉड्यूल" अपने मूल पैकेज को आयात किए बिना आयात करने योग्य है, तो मज़बूती से जांचने का कोई तरीका नहीं है। यह कहते हुए, समस्या के कई समाधान हैं "यह कैसे जांचना है कि क्या पायथन मॉड्यूल मौजूद है"।

नीचे दिए गए समाधान से उस समस्या का समाधान होता है, जो आयातित मॉड्यूल ImportError को बढ़ा सकता है यहां तक ​​कि यह मौजूद है। हम उस स्थिति को इस तरह से अलग करना चाहते हैं जिसमें मॉड्यूल मौजूद नहीं है।

अजगर 2 :

import importlib
import pkgutil
import sys

def find_module(full_module_name):
    """
    Returns module object if module `full_module_name` can be imported. 

    Returns None if module does not exist. 

    Exception is raised if (existing) module raises exception during its import.
    """
    module = sys.modules.get(full_module_name)
    if module is None:
        module_path_tail = full_module_name.split('.')
        module_path_head = []
        loader = True
        while module_path_tail and loader:
            module_path_head.append(module_path_tail.pop(0))
            module_name = ".".join(module_path_head)
            loader = bool(pkgutil.find_loader(module_name))
            if not loader:
                # Double check if module realy does not exist
                # (case: full_module_name == 'paste.deploy')
                try:
                    importlib.import_module(module_name)
                except ImportError:
                    pass
                else:
                    loader = True
        if loader:
            module = importlib.import_module(full_module_name)
    return module

अजगर 3 :

import importlib

def find_module(full_module_name):
    """
    Returns module object if module `full_module_name` can be imported. 

    Returns None if module does not exist. 

    Exception is raised if (existing) module raises exception during its import.
    """
    try:
        return importlib.import_module(full_module_name)
    except ImportError as exc:
        if not (full_module_name + '.').startswith(exc.name + '.'):
            raise

1

in django.utils.module_loading.module_has_submodule


import sys
import os
import imp

def module_has_submodule(package, module_name):
    """
    check module in package
    django.utils.module_loading.module_has_submodule
    """
    name = ".".join([package.__name__, module_name])
    try:
        # None indicates a cached miss; see mark_miss() in Python/import.c.
        return sys.modules[name] is not None
    except KeyError:
        pass
    try:
        package_path = package.__path__   # No __path__, then not a package.
    except AttributeError:
        # Since the remainder of this function assumes that we're dealing with
        # a package (module with a __path__), so if it's not, then bail here.
        return False
    for finder in sys.meta_path:
        if finder.find_module(name, package_path):
            return True
    for entry in package_path:
        try:
            # Try the cached finder.
            finder = sys.path_importer_cache[entry]
            if finder is None:
                # Implicit import machinery should be used.
                try:
                    file_, _, _ = imp.find_module(module_name, [entry])
                    if file_:
                        file_.close()
                    return True
                except ImportError:
                    continue
            # Else see if the finder knows of a loader.
            elif finder.find_module(name):
                return True
            else:
                continue
        except KeyError:
            # No cached finder, so try and make one.
            for hook in sys.path_hooks:
                try:
                    finder = hook(entry)
                    # XXX Could cache in sys.path_importer_cache
                    if finder.find_module(name):
                        return True
                    else:
                        # Once a finder is found, stop the search.
                        break
                except ImportError:
                    # Continue the search for a finder.
                    continue
            else:
                # No finder found.
                # Try the implicit import machinery if searching a directory.
                if os.path.isdir(entry):
                    try:
                        file_, _, _ = imp.find_module(module_name, [entry])
                        if file_:
                            file_.close()
                        return True
                    except ImportError:
                        pass
                # XXX Could insert None or NullImporter
    else:
        # Exhausted the search, so the module cannot be found.
        return False

यह मेरे मानक प्रश्न को पूरा करता है जब प्रोग्रामिंग पायथन: WWDD (व्हाट्सएप Django Do?) और मुझे वहाँ देखना चाहिए
yarbelk
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.