web-dev-qa-db-ja.com

importlib.utilを使用してライブラリをチェックするときにエラーが発生しました

Importlibライブラリを使用して、Python 3.5.2でスクリプトを実行しているコンピューターにnmapライブラリがインストールされているかどうかを確認しようとしています。

importlib.util.find_spec("nmap")を使おうとしていますが、次のエラーが表示されます。

>>> import importlib
>>> importlib.util.find_spec("nmap")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'

誰かが私がどこで間違っているのか教えてもらえますか?

[〜#〜]編集[〜#〜]

次のコードを使用して、関数を機能させることができました。

#!/usr/bin/pythonw

import importlib
from importlib import util

#check to see if nmap module is installed
find_nmap = util.find_spec("nmap")
if find_nmap is None:
    print("Error")
10
DKNUCKLES

これを試して:

_from importlib import util
util.find_spec("nmap")
_

調査するつもりですが、正直なところ、なぜ一方が機能し、もう一方が機能しないのかわかりません。また、次のインタラクティブセッションを確認してください。

_>>> import importlib
>>> importlib.util
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'
>>> from importlib import util
>>> util
<module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'>
>>> importlib.util
<module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'>
_

だから...ええ。これは誰かにとっては完全に理にかなっていると確信していますが、私にとってはそうではありません。わかり次第更新します。

更新:

これを次のようなものと比較します。

_>>> import datetime
>>> datetime
<module 'datetime' from '/usr/lib/python3.5/datetime.py'>
>>> datetime.datetime
<class 'datetime.datetime'>
_

違いは、この場合、最初のdatetimeがモジュールで、2番目がクラスであるのに対し、_importlib.util_の場合は両方がモジュールであるということです。したがって、おそらく_module.module_は両方のモジュールからのコードがロードされていない限りOKではありませんが、_module.class_はモジュールのインポート時にクラスコードがロードされるためOKです。

アップデート#2

いいえ、多くの場合、_module.module_で問題ないようです。例えば:

_>>> import urllib
>>> urllib
<module 'urllib' from '/usr/lib/python3.5/urllib/__init__.py'>
>>> urllib.error
<module 'urllib.error' from '/usr/lib/python3.5/urllib/error.py'>
_

したがって、おそらくそれはimportlibに固有のものです。

アップデート#3

コメントで@ kfbが指摘しているように、具体的にはimportlibに関連しているようです。 ___init__.py_ for importlib からの次のコメントを参照してください。

_# Until bootstrapping is complete, DO NOT import any modules that attempt
# to import importlib._bootstrap (directly or indirectly). Since this
# partially initialised package would be present in sys.modules, those
# modules would get an uninitialised copy of the source version, instead
# of a fully initialised version (either the frozen one or the one
# initialised below if the frozen one is not available).
_

_importlib/util.py_doesimport _importlib._bootstrap_なので、これは実現されていると思います。私の理解が正しければ、_import importlib_を実行すると、サブモジュールは初期化されますが、インポートしたimportlibモジュールオブジェクトに対しては初期化されません。この時点で、dir(importlib)を実行すると、utilは表示されません。興味深いことに、after_importlib.util_にアクセスしようとして、AttributeErrorutil(および他のサブモジュール)がロードされました/ initialize、そして今あなたはできる_importlib.util_にアクセスできます!

_>>> import importlib
>>> dir(importlib)
['_RELOADING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__import__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bootstrap', '_bootstrap_external', '_imp', '_r_long', '_w_long', 'find_loader', 'import_module', 'invalidate_caches', 'reload', 'sys', 'types', 'warnings']
>>> importlib.util
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'importlib' has no attribute 'util'
>>> importlib.util
<module 'importlib.util' from '/usr/lib/python3.5/importlib/util.py'>
>>> dir(importlib)
['_RELOADING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__import__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bootstrap', '_bootstrap_external', '_imp', '_r_long', '_w_long', 'abc', 'find_loader', 'import_module', 'invalidate_caches', 'machinery', 'reload', 'sys', 'types', 'util', 'warnings']
_
17
elethan