Tôi cần biết nếu một mô-đun python tồn tại, mà không cần nhập nó.
Nhập một cái gì đó có thể không tồn tại (không phải những gì tôi muốn):
try:
import eggs
except ImportError:
pass
Tôi cần biết nếu một mô-đun python tồn tại, mà không cần nhập nó.
Nhập một cái gì đó có thể không tồn tại (không phải những gì tôi muốn):
try:
import eggs
except ImportError:
pass
Câu trả lời:
Để kiểm tra xem nhập có thể tìm thấy cái gì đó trong python2 hay không, bằng cách sử dụng imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
Để tìm hàng nhập khẩu chấm, bạn cần làm thêm:
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
Bạn cũng có thể sử dụng pkgutil.find_loader
(ít nhiều giống với phần python3
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Bạn nên sử dụng importlib
, Làm thế nào tôi đã làm điều này là:
import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None
Kỳ vọng của tôi là, nếu bạn có thể tìm thấy một trình tải cho nó, thì nó tồn tại. Bạn cũng có thể thông minh hơn một chút về nó, như lọc ra những bộ tải bạn sẽ chấp nhận. Ví dụ:
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)
Trong Python3.4 importlib.find_loader
tài liệu python không được ủng hộ importlib.util.find_spec
. Phương pháp được đề xuất là importlib.util.find_spec
. Có những thứ khác giống như importlib.machinery.FileFinder
, rất hữu ích nếu bạn đang tải một tệp cụ thể. Tìm hiểu làm thế nào để sử dụng chúng là vượt quá phạm vi của điều này.
import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None
Điều này cũng hoạt động với nhập khẩu tương đối nhưng bạn phải cung cấp gói bắt đầu, vì vậy bạn cũng có thể làm:
import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"
Trong khi tôi chắc chắn có một lý do để làm điều này - tôi không chắc nó sẽ là gì.
Khi cố gắng tìm một mô hình con, nó sẽ nhập mô đun mẹ (cho tất cả các phương thức trên)!
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')
ý kiến hoan nghênh về việc này
find_loader
eggs.ham.spam
.
spam
trong eggs.ham
bạn sẽ sử dụngimp.find_module('spam', ['eggs', 'ham'])
pkgutil.find_loader("my.package.module")
trả về một trình tải nếu gói / mô-đun tồn tại và None
nếu không. Vui lòng cập nhật câu trả lời của bạn cho Python 2, vì việc che giấu ImportError đã khiến tôi phát điên ngày hôm qua xP
Sau khi sử dụng phản hồi của yarbelk, tôi đã thực hiện điều này để không phải nhập ìmp
.
try:
__import__('imp').find_module('eggs')
# Make things with supposed existing module
except ImportError:
pass
Hữu ích trong Django settings.py
chẳng hạn.
Nó ModuleNotFoundError
đã được giới thiệu trong python 3.6 và có thể được sử dụng cho mục đích này
try:
import eggs
except ModuleNotFoundError:
# Error handling
pass
Lỗi được đưa ra khi một mô-đun hoặc một trong các cha mẹ của nó không thể được tìm thấy. Vì thế
try:
import eggs.sub
except ModuleNotFoundError as err:
# Error handling
print(err)
sẽ in một thông báo trông giống như No module named 'eggs'
nếu eggs
mô-đun không thể được tìm thấy; nhưng sẽ in một cái gì đó giống như No module named 'eggs.sub'
nếu sub
không thể tìm thấy mô-đun nhưng eggs
có thể tìm thấy gói.
Xem tài liệu của hệ thống nhập khẩu để biết thêm thông tin vềModuleNotFoundError
Cho đến khi câu trả lời hiện tại được cập nhật, đây là cách cho Python 2
import pkgutil
import importlib
if pkgutil.find_loader(mod) is not None:
return importlib.import_module(mod)
return None
Rất nhiều câu trả lời sử dụng bắt một ImportError
. Vấn đề với điều đó là, chúng ta không thể biết cái gì némImportError
.
Nếu bạn nhập mô-đun tồn tại của bạn và có một ImportError
mô-đun trong mô-đun của bạn (ví dụ: lỗi đánh máy trên dòng 1), kết quả sẽ là mô-đun của bạn không tồn tại. Bạn sẽ mất khá nhiều thời gian để quay lại để nhận ra rằng mô-đun của bạn tồn tại và ImportError
bị bắt và khiến mọi thứ thất bại trong âm thầm.
ImportError
- vui lòng chỉnh sửa nếu nó không rõ ràng với bạn.
câu trả lời của go_as như một lớp lót
python -c "help('modules');" | grep module
Tôi đã gặp câu hỏi này trong khi tìm kiếm một cách để kiểm tra xem một mô-đun có được tải từ dòng lệnh hay không và muốn chia sẻ suy nghĩ của tôi cho những người đến sau tôi và tìm kiếm tương tự:
Phương pháp tệp tập lệnh Linux / UNIX : tạo một tệp module_help.py
:
#!/usr/bin/env python
help('modules')
Sau đó, đảm bảo rằng nó có thể thực thi được: chmod u+x module_help.py
Và gọi nó với một pipe
đến grep
:
./module_help.py | grep module_name
Gọi hệ thống trợ giúp tích hợp . (Chức năng này dành cho sử dụng tương tác .) Nếu không có đối số nào được đưa ra, hệ thống trợ giúp tương tác sẽ khởi động trên bảng điều khiển trình thông dịch. Nếu đối số là một chuỗi , thì chuỗi đó được tra cứu dưới dạng tên của mô-đun , hàm, lớp, phương thức, từ khóa hoặc chủ đề tài liệu và một trang trợ giúp được in trên bàn điều khiển. Nếu đối số là bất kỳ loại đối tượng nào khác, một trang trợ giúp về đối tượng sẽ được tạo.
Phương thức tương tác : trong tải giao diện điều khiểnpython
>>> help('module_name')
Nếu tìm thấy hãy bỏ đọc bằng cách gõ q
Để thoát phiên tương tác python, nhấn Ctrl+D
Phương pháp tệp tập lệnh Windows cũng tương thích với Linux / UNIX và tốt hơn về tổng thể :
#!/usr/bin/env python
import sys
help(sys.argv[1])
Gọi nó từ lệnh như:
python module_help.py site
Sẽ xuất:
Trợ giúp trên trang web mô-đun:
NAME
trang web - Nối các đường dẫn tìm kiếm mô-đun cho các gói của bên thứ ba vào sys.path.
FILE
/usr/lib/python2.7/site.py
MODULE DOCS
http://docs.python.org/l Library / site
DESCRIPTION
...
:
và bạn phải nhấn q
để thoát chế độ tương tác.
Sử dụng mô-đun chưa biết:
python module_help.py lkajshdflkahsodf
Sẽ xuất:
không tìm thấy tài liệu Python nào cho 'lkajshdflkahsodf'
và thoát.
Sử dụng một trong các chức năng từ pkgutil , ví dụ:
from pkgutil import iter_modules
def module_exists(module_name):
return module_name in (name for loader, name, ispkg in iter_modules())
Một câu lệnh if đơn giản hơn từ AskUbfox: Làm cách nào để kiểm tra xem một mô-đun có được cài đặt trong Python không?
import sys
print('eggs' in sys.modules)
Bạn chỉ có thể viết một tập lệnh nhỏ sẽ cố gắng nhập tất cả các mô-đun và cho bạn biết cái nào bị lỗi và cái nào đang hoạt động:
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))
Đầu ra:
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
...
Lời cảnh báo này sẽ cố gắng nhập mọi thứ để bạn sẽ thấy những thứ như PyYAML failed with error code: No module named pyyaml
vì tên nhập thực tế chỉ là yaml. Vì vậy, miễn là bạn biết hàng nhập khẩu của mình, điều này sẽ giúp bạn thực hiện thủ thuật này.
Tôi đã viết chức năng trợ giúp này:
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
Không có cách nào để kiểm tra một cách đáng tin cậy nếu "mô-đun chấm" có thể nhập được mà không cần nhập gói chính của nó. Nói điều này, có nhiều giải pháp cho vấn đề "làm thế nào để kiểm tra xem mô-đun Python có tồn tại không".
Giải pháp bên dưới giải quyết vấn đề mô-đun nhập khẩu có thể nâng cao ImportError ngay cả khi nó tồn tại. Chúng tôi muốn phân biệt tình huống đó với mô-đun không tồn tại.
Con trăn 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
Con trăn 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
trong 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