পাইথন মডিউলটি আমদানি না করে কীভাবে উপস্থিত রয়েছে তা কীভাবে পরীক্ষা করবেন


179

আমদানি না করে পাইথন মডিউলটি রয়েছে কিনা তা আমার জানতে হবে।

এমন কিছু আমদানি করা যা হয়ত অস্তিত্বহীন (আমি যা চাই তা নয়):

try:
    import eggs
except ImportError:
    pass

4
আমি কৌতূহলী, আমদানি ব্যবহারের ডাউনসাইডগুলি কী?
চক

15
যদি আপনার মডিউলটির পার্শ্ব প্রতিক্রিয়া থাকে, কলিং আমদানির অযাচিত ফলাফল হতে পারে। সুতরাং, আপনি যদি প্রথমে কোনও ফাইলের কোন সংস্করণটি চালিত করতে চান তা নীচের উত্তর দিয়ে চেক করতে পারেন এবং পরে আমদানি করতে পারেন। আমি পার্শ্ব প্রতিক্রিয়া সহ মডিউলগুলি লেখার পক্ষে ভাল ধারণা প্রস্তাব দিচ্ছি না - তবে আমরা সকলেই প্রাপ্তবয়স্ক এবং আমরা কীভাবে বিপজ্জনকভাবে কোডিং করতে চাই তার নিজের সিদ্ধান্ত নিতে পারি।
ইয়ারবেলক


1
@ArtOfWarfare আমি শুধু বন্ধ করে প্রশ্ন সদৃশ হিসাবে লিঙ্ক এই এক। কারণ এই প্রশ্নটি আরও স্পষ্ট এবং এখানে প্রস্তাবিত সমাধানটি এখানে তালিকাভুক্ত অন্যান্য সমস্ত চেয়ে ভাল। আমি বরং এটিকে নির্দেশিত করব যারাই এর থেকে ভাল সমাধানের উত্তর চায়, মানুষকে এ থেকে দূরে সরিয়ে দেওয়ার চেয়ে।
বাকুরিউ

7
@ চক অতিরিক্তভাবে মডিউলটির উপস্থিতি থাকতে পারে তবে এতে আমদানি ত্রুটি থাকতে পারে। উপরের কোড হিসাবে আমদানি ত্রুটিগুলি ধরা মডিউলটির অস্তিত্বের ইঙ্গিত দিতে পারে, যদি সত্যই এটি হয় তবে ত্রুটি রয়েছে।
মাইকেল বার্টন

উত্তর:


199

Python2

আমদানি ব্যবহার করে পাইথন 2 তে কিছু খুঁজে পেতে পারে কিনা তা পরীক্ষা করে দেখুন 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_loader(পাইথন 3 অংশের মতো কম-বেশি একই

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 ≥ 3.4

importlib.find_loader পাইথন 3.4 তে পাইথন ডক্সের পক্ষে অবহেলা করা হয়েছিল 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')

মন্তব্য এই কাছাকাছি পেয়ে স্বাগত জানাই

প্রাপ্তি স্বীকার

  • ইমপোর্টলিবের জন্য
  • পাইথন ৩৩.৩ এর জন্য @ লুকাশ-গাইডো ric find_loader
  • পাইকগটিলস.ফাইন্ড_লোডার আচরণের জন্য @ স্পেন_এক্সটি পাইথন ২..7

3
এটি কেবল শীর্ষ-স্তরের মডিউলগুলির জন্য কাজ করে, এর জন্য নয় eggs.ham.spam
হেমফ্লিট

3
@hemflit যদি আপনি খুঁজে পেতে চান spamমধ্যে eggs.hamআপনি ব্যবহার করেনimp.find_module('spam', ['eggs', 'ham'])
gitaarik

5
+1 টি, কিন্তু impকরা হয় অবচিত পক্ষে importlib3. পাইথন মধ্যে
rvighne

4
যদি আমদানি করা মডিউলটিতে একটি আসল "আমদানি" থাকে What আমার সাথে এটাই হচ্ছিল। তারপরে মডিউলটি বিদ্যমান তবে "পাওয়া যাবে না"।
এনপেনাক্স

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উদাহরণস্বরূপ জাজানোতে দরকারী ।


4
আমি হ্রাস পেয়েছি, কারণ এই মুখোশগুলি মডিউলটিতে ত্রুটিগুলি আমদানি করে, যা ত্রুটিটি চিহ্নিত করা সত্যই শক্ত করে তোলে।
এনপেনাক্স

1
ডাউনভোট একটি খারাপ ধারণা, একটি ভাল অভ্যাস হ'ল "সর্বদা লগ ক্যাচ করা ত্রুটি"। আপনি এটি কীভাবে চান তা লেখার পরে এটি একটি উদাহরণ।
জুলু

2
যদি আমদানি করা মডিউলটি 1 ইম্পোর্টেররের সাথে লাইন 1 এ ব্যর্থ হয় এবং আপনার চেষ্টা ক্যাচটি নিঃশব্দে ব্যর্থ করে দেয় আপনি কীভাবে একটি ত্রুটি লগ করবেন?
এনপেনেক্স

আমি সত্যিকারের জীবনে এখনই মাস্কিং-আমদানি-ত্রুটিগুলির ইস্যুটি চালিয়েছি, এবং এটি খারাপ ছিল (যে পরীক্ষাগুলি পাস করতে ব্যর্থ হওয়া উচিত ছিল!) Causing
ডেভিড

যেখানে কেউ যে ত্রুটি ব্যবহার করছিলেন একটি ভিন্ন মডিউল উপর একটি monkeypatch ট্রিগার আমি যে গাড়ীতে আঘাত ... যেটা ছিল উন্মাদ এটি
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
এই doe প্রশ্নের উত্তর দেয় না কারণ এটি উপস্থিত থাকলে প্যাকেজটি আমদানি করে
ডাইভেক্স

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 উদাহরণে ইম্পোর্টেরর ক্যাচ ব্যবহার করছি। তারা সেখানে কেন, তাহলে?
এনপেনাক্স

3
এটি মোড == 'not_existing_package.mymodule' হলে আমদানি ত্যাগ করে। নীচে
মার্সিন রেসিজিস্কি

1
অবশ্যই এটি একটি আমদানি ত্রুটি ছুড়ে ফেলে। কোনও মডিউল উপস্থিত না থাকলে এটি একটি আমদানি ত্রুটি নিক্ষেপ করার কথা। আপনার প্রয়োজন হলে আপনি এটি ধরতে পারেন। অন্যান্য সমাধানগুলির সাথে সমস্যাটি হ'ল তারা অন্যান্য ত্রুটিগুলি মুখোশ করে।
এনপেনেক্স

চেষ্টা করুন / বাদে এর অর্থ এই নয় যে আপনার অবশ্যই জিনিসগুলি লগ করা বা নিশ্চিত করা উচিত নয়। আপনি যে কোনও অন্তর্নিহিত ট্রেসব্যাক পুরোপুরি ধরতে পারেন এবং যা কিছু করতে চান তা করতে পারেন।
জুলু

8

ওয়ান লাইনার হিসাবে go_as এর উত্তর

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

6

কমান্ড লাইন থেকে কোনও মডিউল লোড করা হয়েছে কিনা তা যাচাই করার উপায় অনুসন্ধান করার সময় আমি এই প্রশ্নটি জুড়ে এসেছি এবং আমার পরে আসা এবং এটির জন্য অনুসন্ধানকারীদের জন্য আমার মতামতগুলি ভাগ করে নিতে চাই:

লিনাক্স / ইউনিক্স স্ক্রিপ্ট ফাইল পদ্ধতি : একটি ফাইল তৈরি করুন 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' এর জন্য পাইথনের কোনও ডকুমেন্টেশন পাওয়া যায়নি

এবং প্রস্থান করুন।




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কারণ আসল আমদানির নামটি কেবল ইয়ামল। সুতরাং যতক্ষণ আপনি নিজের আমদানি জানেন এটি আপনার পক্ষে কৌশলটি করা উচিত।


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

"ডটেড মডিউল" এর প্যারেন্ট প্যাকেজটি আমদানি না করে আমদানিযোগ্য কিনা তা নির্ভরযোগ্যভাবে পরীক্ষা করার কোনও উপায় নেই। এটি বলে, "পাইথন মডিউলটি বিদ্যমান কিনা তা কীভাবে পরীক্ষা করবেন" সমস্যার অনেকগুলি সমাধান রয়েছে।

সমাধানের নীচে যে সমস্যার সমাধান করা হয়েছে তা আমদানি করা মডিউল আমদানি ত্রুটি এমনকি এটি বিদ্যমান থাকতে পারে। আমরা সেই পরিস্থিতিকে এমন থেকে আলাদা করতে চাই যেখানে মডিউলটির অস্তিত্ব নেই।

পাইথন 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

django.utils.module_loading.module_as_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 (কি জ্যাঙ্গো করবেন?) আর আমি বর্ণন সেখানে থাকতে হবে: এটা আমার মান প্রশ্ন যখন পাইথন প্রোগ্রামিং পরিপূর্ণ
yarbelk
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.