importlib --- import の実装¶
Added in version 3.1.
ソースコード: Lib/importlib/__init__.py
はじめに¶
importlib パッケージの目的は3つあります。
1 つ目は import 文 (ひいては __import__() 関数) の実装を Python のソースコードで提供することです。
これにより、どの Python インタープリターにも移植できる import の実装を提供します。
また、Python 以外のプログラミング言語による実装よりも理解しやすい実装になります。
2つ目の目的は、このパッケージが公開している import を実装するための要素を利用して、(インポーター として知られる) インポートプロセスで動作するカスタムのオブジェクトを実装しやすくすることです。
3 つ目は、Python パッケージのさまざまな側面を管理する追加機能を提供するモジュールを含むことです。
importlib.metadataはサードパーティの配布物のメタデータへのアクセスを提供します。importlib.resourcesは Python パッケージ内のコード以外の「リソース」にアクセスする機能を提供します。
参考
- import 文
import文の言語リファレンス。- Packages specification
パッケージの元の仕様。幾つかの動作はこの仕様が書かれた頃から変更されています (例:
sys.modulesでNoneに基づくリダイレクト)。__import__()関数import文はこの関数のシンタックスシュガーです。- sys.path モジュール検索パスの初期化
sys.pathの初期化について説明します。- PEP 235
大文字小文字を区別しないプラットフォームでのインポート
- PEP 263
Python のソースコードのエンコーディング
- PEP 302
新しいインポートフック
- PEP 328
複数行のインポートと、絶対/相対インポート
- PEP 366
main モジュールの明示的な相対インポート
- PEP 420
暗黙的な名前空間パッケージ
- PEP 451
インポートシステムのための ModuleSpec 型
- PEP 488
PYO ファイルの撤廃
- PEP 489
複数フェーズでの拡張モジュールの初期化
- PEP 552
決定論的 pyc
- PEP 3120
デフォルトのソースエンコーディングとして UTF-8 を使用
- PEP 3147
PYC リポジトリディレクトリ
関数¶
- importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)¶
組み込みの
__import__()関数の実装です。注釈
プログラムからモジュールをインポートする場合はこの関数の代わりに
import_module()を使ってください。
- importlib.import_module(name, package=None)¶
モジュールをインポートします。name 引数は、インポートするモジュールを絶対または相対表現 (例えば
pkg.modまたは..mod) で指定します。name が相対表現で与えられたら、package 引数を、パッケージ名を解決するためのアンカーとなるパッケージの名前に設定する必要があります (例えばimport_module('..mod', 'pkg.subpkg')はpkg.modをインポートします)。import_module()関数はimportlib.__import__()を単純化するラッパーとして働きます。つまり、この関数のすべての意味はimportlib.__import__()から受け継いでいます。これらの2つの関数の最も重要な違いは、import_module()が指定されたパッケージやモジュール (例えばpkg.mod) を返すのに対し、__import__()はトップレベルのパッケージやモジュール (例えばpkg) を返すことです。もしモジュールを動的にインポートしていて、インタープリタの実行開始後にモジュールが作成された (例えば、 Python ソースファイルを作成した) 場合、インポートシステムが新しいモジュールを見つけられるように、
invalidate_caches()を呼ぶ必要があるでしょう。バージョン 3.3 で変更: 親パッケージは自動的にインポートされます。
- importlib.invalidate_caches()¶
sys.meta_pathに保存されたファインダーの内部キャッシュを無効にします。 ファインダーがinvalidate_caches()を実装していれば、無効化のために呼び出します。 プログラムの実行中にモジュールを作成またはインストールした場合は、すべてのファインダーが新しいモジュールの存在を認識できるよう、この関数を呼び出してください。Added in version 3.3.
バージョン 3.10 で変更: 同じ名前空間をすでにインポートした後に、
sys.pathの別の場所に作成またはインストールされた名前空間パッケージも認識するようになりました。
- importlib.reload(module)¶
以前にインポートされた module をリロードします。引数はモジュールオブジェクトでなければならず、したがってそれ以前に必ずインポートに成功していなければなりません。この関数は、モジュールのソースファイルを外部エディタで編集していて Python インタープリタから離れることなく新しいバージョンを試したい際に便利です。戻り値はモジュールオブジェクトです。 (もし再インポートが異なるオブジェクトを
sys.modulesに配置したら、元の module とは異なるかもしれません。)reload()が実行された場合:Python モジュールのコードは再コンパイルされ、モジュールレベルのコードが再度実行されます。モジュールの辞書中にある何らかの名前に結び付けられたオブジェクトは、そのモジュールを最初にロードしたときの ローダー を再利用して新たに定義されます。拡張モジュールの
init関数が二度呼び出されることはありません。Python における他のオブジェクトと同様、以前のオブジェクトのメモリ領域は、参照カウントがゼロにならないかぎり再利用されません。
モジュール名前空間内の名前は新しいオブジェクト (または更新されたオブジェクト) を指すよう更新されます。
以前のオブジェクトが (外部の他のモジュールなどからの) 参照を受けている場合、それらを新たなオブジェクトに再束縛し直すことはないので、必要なら自分で名前空間を更新しなければなりません。
いくつか補足説明があります:
モジュールが再ロードされた際、その辞書 (モジュールのグローバル変数を含みます) はそのまま残ります。名前の再定義を行うと、以前の定義を上書きするので、一般的には問題はありません。新たなバージョンのモジュールが古いバージョンで定義された名前を定義していない場合、古い定義がそのまま残ります。辞書がグローバルテーブルやオブジェクトのキャッシュを維持していれば、この機能をモジュールを有効性を引き出すために使うことができます --- つまり、
try文を使えば、必要に応じてテーブルがあるかどうかをテストし、その初期化を飛ばすことができます:try: cache except NameError: cache = {}
組み込みモジュールや動的にロードされるモジュールを再ロードすることは、一般的にそれほど便利ではありません。
sys,__main__,builtinsやその他重要なモジュールの再ロードはお勧め出来ません。 多くの場合、拡張モジュールは 複数回初期化されるようには設計されておらず、再ロードされた場合には何らかの理由で失敗するかもしれません。一方のモジュールが
from...import... を使って、オブジェクトを他方のモジュールからインポートしているなら、他方のモジュールをreload()で呼び出しても、そのモジュールからインポートされたオブジェクトを再定義することはできません --- この問題を回避する一つの方法は、from文を再度実行することで、もう一つの方法はfrom文の代わりにimportと限定的な名前 (module.name) を使うことです。あるモジュールがクラスのインスタンスを生成している場合、そのクラスを定義しているモジュールの再ロードはそれらインスタンスのメソッド定義に影響しません --- それらは古いクラス定義を使い続けます。これは派生クラスの場合でも同じです。
Added in version 3.4.
バージョン 3.7 で変更: リロードされたモジュールの
ModuleSpecが欠けていたときはModuleNotFoundErrorが送出されます。警告
This function is not thread-safe. Calling it from multiple threads can result in unexpected behavior. It's recommended to use the
threading.Lockor other synchronization primitives for thread-safe module reloading.
importlib.abc -- インポートに関連する抽象基底クラス¶
ソースコード: Lib/importlib/abc.py
importlib.abc モジュールは、 import に使われるすべてのコア抽象基底クラス含みます。コア抽象基底クラスの実装を助けるために、コア抽象基底クラスのサブクラスもいくつか提供されています。
抽象基底クラス階層:
object
+-- MetaPathFinder
+-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
- class importlib.abc.MetaPathFinder¶
meta path finder を表す抽象基底クラスです。
Added in version 3.3.
バージョン 3.10 で変更:
Finderのサブクラスではなくなりました。- find_spec(fullname, path, target=None)¶
指定されたモジュールの スペック を検索する抽象メソッドです。 トップレベルのインポートの場合、path は
Noneです。 それ以外の場合はサブパッケージやモジュールの検索で、path は親パッケージの__path__の値です。 スペックが見つからなければNoneを返します。targetが渡される場合はモジュールオブジェクトであり、ファインダーが返すスペックをより的確に判断するために使えます。 具体的なMetaPathFindersの実装には、importlib.util.spec_from_loader()が役立つ場合があります。Added in version 3.4.
- invalidate_caches()¶
このファインダーで使われている内部キャッシュがあれば無効にするオプションのメソッドです。
sys.meta_path上のすべてのファインダーのキャッシュを無効化する際、importlib.invalidate_caches()によって使われます。バージョン 3.4 で変更: 呼び出された際に
NotImplementedではなくNoneを返すようになりました。
- class importlib.abc.PathEntryFinder¶
path entry finder を表す抽象基底クラスです。
MetaPathFinderと似ているところがありますが、PathEntryFinderはimportlib.machinery.PathFinderが提供するパスに基づく import サブシステムの中でのみ使うことが意図されています。Added in version 3.3.
バージョン 3.10 で変更:
Finderのサブクラスではなくなりました。- find_spec(fullname, target=None)¶
指定されたモジュールに対応する スペック を検索する抽象メソッド。ファインダーは、割り当てられている パス・エントリー 内のモジュールだけを検索します。スペックが見つからなければ
Noneが返されます。targetは、渡されてきたならモジュールオブジェクトです。これはファインダーがどのようなスペックを返せばよいか推測するために使用します。具体的なPathEntryFindersを実装するためにはimportlib.util.spec_from_loader()が便利かもしれません。Added in version 3.4.
- invalidate_caches()¶
このファインダーで使われている内部キャッシュがあれば無効にするオプションのメソッドです。キャッシュされたすべてのファインダーの無効化する際、
importlib.machinery.PathFinder.invalidate_caches()によって使われます。
- class importlib.abc.Loader¶
loader の抽象基底クラスです。ローダーの厳密な定義は PEP 302 を参照してください。
Loaders that wish to support resource reading should implement a
get_resource_reader()method as specified byimportlib.resources.abc.ResourceReader.バージョン 3.7 で変更: Introduced the optional
get_resource_reader()method.- create_module(spec)¶
モジュールをインポートする際に使用されるモジュールオブジェクトを返すメソッド。このメソッドは
Noneを戻すことができ、その場合はデフォルトのモジュール作成のセマンティクスが適用されることを示します。Added in version 3.4.
バージョン 3.6 で変更:
exec_module()が定義されている場合は、このメソッドはオプションではなくなりました。
- exec_module(module)¶
モジュールがインポートまたはリロードされる際に、そのモジュールをモジュール自身の名前空間の中で実行する抽象的なメソッド。
exec_module()が呼ばれる時点で、モジュールはすでに初期設定されている必要があります。 このメソッドが存在するときは、create_module()の定義が必須です。Added in version 3.4.
バージョン 3.6 で変更:
create_module()の定義が必須となりました。
- load_module(fullname)¶
モジュールをロードするためのレガシーなメソッドです。モジュールがロードできなければ
ImportErrorを送出し、ロードできればロードされたモジュールを返します。If the requested module already exists in
sys.modules, that module should be used and reloaded. Otherwise the loader should create a new module and insert it intosys.modulesbefore any loading begins, to prevent recursion from the import. If the loader inserted a module and the load fails, it must be removed by the loader fromsys.modules; modules already insys.modulesbefore the loader began execution should be left alone.ローダーはモジュールにいくつかの属性を設定する必要があります。(なお、これらの属性には、モジュールがリロードされた際に変化するものがあります):
module.__cached__(deprecated)module.__package__(deprecated)module.__loader__(deprecated)
exec_module()が利用可能な場合、後方互換な機能が提供されます。バージョン 3.4 で変更: Raise
ImportErrorwhen called instead ofNotImplementedError. Functionality provided whenexec_module()is available.Deprecated since version 3.4, will be removed in version 3.15: モジュールをロードするための推奨される API は、
exec_module()(およびcreate_module()) です。ローダーはload_module()の代わりにそれを実装するべきです。exec_module()が実装されている場合、インポート機構はload_module()の他のすべての責任を肩代わりします。
- class importlib.abc.ResourceLoader¶
TraversableResources に取って代わられました
loader の抽象基底クラスで、ストレージバックエンドから任意のリソースをロードするオプションの PEP 302 プロトコルを実装します。
バージョン 3.7 で非推奨: This ABC is deprecated in favour of supporting resource loading through
importlib.resources.abc.TraversableResources.
- class importlib.abc.InspectLoader¶
loader の抽象基底クラスで、ローダーがモジュールを検査するためのオプションの PEP 302 プロトコルを実装します。
- get_code(fullname)¶
モジュールの
codeオブジェクトを返すか、 (例えば組み込みモジュールの場合に) モジュールがコードオブジェクトを持たなければNoneを返します。要求されたモジュールをローダーが見つけられなかった場合はImportErrorを送出します。注釈
このメソッドにはデフォルト実装がありますが、とはいえパフォーマンスのために、可能ならばオーバライドしたほうが良いです。
バージョン 3.4 で変更: このメソッドはもはや抽象メソッドではなく、具象実装が提供されます。
- abstractmethod get_source(fullname)¶
モジュールのソースを返す抽象メソッドです。これは認識されたすべての行セパレータを
'\n'文字に変換し、 universal newlines を使ったテキスト文字列として返されます。利用できるソースがなければ (例えば組み込みモジュール)、Noneを返します。指定されたモジュールが見つからなければ、ImportErrorを送出します。バージョン 3.4 で変更:
NotImplementedErrorの代わりにImportErrorを送出します。
- is_package(fullname)¶
モジュールがパッケージであれば True を返し、そうでなければ False を返すオプションのメソッドです。 ローダー がモジュールを見つけられなかったなら
ImportErrorが送出されます。バージョン 3.4 で変更:
NotImplementedErrorの代わりにImportErrorを送出します。
- static source_to_code(data, path='<string>')¶
Python のソースからコードオブジェクトを作ります。
data 引数は
compile()関数がサポートするもの (すなわち文字列かバイト) なら何でも構いません。path 引数はソースコードの元々の場所への "パス" でなければなりませんが、抽象概念 (例えば zip ファイル内の場所) でも構いません。結果のコードオブジェクトを使って、
exec(code, module.__dict__)を呼ぶことでモジュール内でコードを実行できます。Added in version 3.4.
バージョン 3.5 で変更: スタティックメソッドになりました。
- exec_module(module)¶
Loader.exec_module()の実装です。Added in version 3.4.
- load_module(fullname)¶
Loader.load_module()の実装です。Deprecated since version 3.4, will be removed in version 3.15: 代わりに
exec_module()を使用してください。
- class importlib.abc.ExecutionLoader¶
InspectLoaderから継承された抽象基底クラスで、実装されていれば、モジュールをスクリプトとして実行する助けになります。この抽象基底クラスはオプションの PEP 302 プロトコルを表します。- abstractmethod get_filename(fullname)¶
指定されたモジュールの
__file__の値を返す抽象メソッドです。 パスが利用できなければImportErrorを送出します。ソースコードが利用できるなら、そのモジュールのロードにバイトコードが使われたかにかかわらず、このメソッドはそのソースファイルへのパスを返す必要があります。
バージョン 3.4 で変更:
NotImplementedErrorの代わりにImportErrorを送出します。
- class importlib.abc.FileLoader(fullname, path)¶
ResourceLoaderとExecutionLoaderから継承された抽象基底クラスで、ResourceLoader.get_data()およびExecutionLoader.get_filename()の具象実装を提供します。fullname 引数は、ローダーが解決しようとするモジュールの、完全に解決された名前です。path 引数は、モジュールのファイルへのパスです。
Added in version 3.3.
- name¶
ローダーが扱えるモジュールの名前です。
- path¶
モジュールのファイルへのパスです。
- load_module(fullname)¶
親クラスの
load_module()を呼び出します。Deprecated since version 3.4, will be removed in version 3.15: 代わりに
Loader.exec_module()を使用してください。
- abstractmethod get_data(path)¶
path をバイナリファイルとして読み込み、そのバイト列を返します。
- class importlib.abc.SourceLoader¶
ソース (オプションでバイトコード) ファイルのロードを実装する抽象基底クラスです。このクラスは、
ResourceLoaderとExecutionLoaderの両方を継承し、以下の実装が必要です:ExecutionLoader.get_filename()ソースファイルへのパスのみを返す必要があります。ソースなしのロードはサポートされていません。
このクラスでこれらの抽象メソッドを定義することで、バイトコードファイルを追加でサポートします。 これらのメソッドを定義しなければ (またはそのメソッドが
NotImplementedErrorを送出すれば)、このローダーはソースコードに対してのみ働きます。 これらのメソッドを実装することで、ローダーはソースとバイトコードファイル の組み合わせ に対して働きます。 バイトコードのみを与えた ソースのない ロードは認められません。 バイトコードファイルは、 Python コンパイラによる解析の工程をなくして速度を上げる最適化です。 ですから、バイトコード特有の API は公開されていません。- path_stats(path)¶
指定されたパスについてのメタデータを含む
dictを返す、オプションの抽象メソッドです。サポートされる辞書のキーは:'mtime'(必須): ソースコードの更新時刻を表す整数または浮動小数点数です。'size'(任意): バイト数で表したソースコードのサイズです。
未来の拡張のため、辞書内の他のキーは無視されます。パスが扱えなければ、
OSErrorが送出されます。Added in version 3.3.
バージョン 3.4 で変更:
NotImplementedErrorの代わりにOSErrorを送出します。
- path_mtime(path)¶
指定されたパスの更新時刻を返す、オプションの抽象メソッドです。
バージョン 3.3 で非推奨: このメソッドは非推奨で、代わりに
path_stats()を使います。 実装する必要はありませんが、互換性のために引き続き利用できます。 パスを扱えない場合はOSErrorを送出してください。バージョン 3.4 で変更:
NotImplementedErrorの代わりにOSErrorを送出します。
- set_data(path, data)¶
ファイルパスに指定されたバイト列を書き込むオプションの抽象メソッドです。存在しない中間ディレクトリがあれば、自動で作成されます。
パスが読み取り専用のために書き込みが失敗した場合 (
errno.EACCES/PermissionError)、例外を伝播させないでください。バージョン 3.4 で変更: 呼ばれたときに
NotImplementedErrorを送出することは最早ありません。
- get_code(fullname)¶
InspectLoader.get_code()の具象実装です。
- exec_module(module)¶
Loader.exec_module()の具象実装です。Added in version 3.4.
- load_module(fullname)¶
Loader.load_module()の具象実装です。Deprecated since version 3.4, will be removed in version 3.15: 代わりに
exec_module()を使用してください。
- get_source(fullname)¶
InspectLoader.get_source()の具象実装です。
- is_package(fullname)¶
InspectLoader.is_package()の具象実装です。モジュールは、次の 両方 を満たすならパッケージであると決定されます。モジュールの (ExecutionLoader.get_filename()で与えられる) ファイルパスが、ファイル拡張子を除くと__init__という名のファイルであること。モジュール名自体が__init__で終わらないこと。
- class importlib.abc.ResourceReader¶
TraversableResources に取って代わられました
resources の読み出し機能を提供する 抽象基底クラス (abstract base class, ABC) です。
この ABC でいう リソース は、パッケージに同梱されるバイナリデータです。 通常は、パッケージの
__init__.pyファイルと同じ場所にあるデータファイルなどを指します。 このクラスの目的は、そのようなデータファイルへのアクセスを抽象化し、パッケージとデータファイルが zip ファイル内にあるかファイルシステム上にあるかなどの違いを意識せずに済むようにすることです。このクラスのどのメソッドでも、resource 引数は概念上は単なるファイル名を表す path-like object でなければなりません。 つまり、resource 引数にサブディレクトリのパスを含めてはいけません。 リーダーが対象とするパッケージの場所が「ディレクトリ」に相当するためです。 この対応関係では、パッケージがディレクトリに、リソースがファイル名に相当します。 このため、このクラスのインスタンスは特定のパッケージと直接対応する必要があり、複数のパッケージやモジュールを表すものではありません。
リソースの読み取りをサポートするローダーは、
get_resource_reader(fullname)というメソッドを提供する必要があります。 このメソッドは、この ABC のインターフェースを実装するオブジェクトを返します。fullnameで指定されたモジュールがパッケージでない場合は、Noneを返さなければなりません。 指定されたモジュールがパッケージである場合にのみ、この ABC と互換性のあるオブジェクトを返してください。Added in version 3.7.
Deprecated since version 3.12, will be removed in version 3.14: 代わりに
importlib.resources.abc.TraversableResourcesを使ってください。- abstractmethod open_resource(resource)¶
resource をバイナリとして読み取るために開いた file-like object を返します。
リソースが見付からない場合は、
FileNotFoundErrorが送出されます。
- abstractmethod resource_path(resource)¶
resource へのファイルシステムパスを返します。
リソースの実体がファイルシステムに存在しない場合、
FileNotFoundErrorが送出されます。
- abstractmethod is_resource(name)¶
name という名前がリソースだと見なせるなら
Trueを返します。 name が存在しない場合はFileNotFoundErrorが送出されます。
- abstractmethod contents()¶
パッケージの内容を文字列で返す iterable を返します。 イテレータが返す名前がすべて実際のリソースを表す必要はありません。 例えば、
is_resource()が偽となる名前を返してもかまいません。リソース以外の名前も返せるのは、パッケージとそのリソースの格納方法があらかじめ分かっていて、そのような名前が役立つ場合に対応するためです。 例えば、パッケージとリソースがファイルシステム上にあると分かっている場合に直接使えるよう、サブディレクトリ名を返すことができます。
この抽象メソッドは、要素を持たないイテラブルを返します。
- class importlib.abc.Traversable¶
ディレクトリの走査やファイルを開く操作に適した、
pathlib.Pathの一部のメソッドを持つオブジェクトです。このオブジェクトをファイルシステム上で表すには、
importlib.resources.as_file()を使ってください。Added in version 3.9.
Deprecated since version 3.12, will be removed in version 3.14: Use
importlib.resources.abc.Traversableinstead.- name¶
抽象属性です。 親への参照を含まない、このオブジェクトのベース名です。
- abstractmethod iterdir()¶
Yield
Traversableobjects inself.
- abstractmethod is_dir()¶
Return
Trueifselfis a directory.
- abstractmethod is_file()¶
Return
Trueifselfis a file.
- abstractmethod joinpath(child)¶
Return Traversable child in
self.
- abstractmethod __truediv__(child)¶
Return
Traversablechild inself.
- abstractmethod open(mode='r', *args, **kwargs)¶
mode に 'r' または 'rb' を指定すると、それぞれテキストまたはバイナリとして開きます。 読み取りに使えるハンドルを返します (
pathlib.Path.openと同じです)。テキストとして開く場合、
io.TextIOWrapperが受け付けるようなエンコーディングの引数を受け付けます。
- read_bytes()¶
Read contents of
selfas bytes.
- read_text(encoding=None)¶
Read contents of
selfas text.
- class importlib.abc.TraversableResources¶
An abstract base class for resource readers capable of serving the
importlib.resources.files()interface. Subclassesimportlib.resources.abc.ResourceReaderand provides concrete implementations of theimportlib.resources.abc.ResourceReader's abstract methods. Therefore, any loader supplyingimportlib.abc.TraversableResourcesalso supplies ResourceReader.リソースの読み取りをサポートするローダーは、このインターフェースを実装する必要があります。
Added in version 3.9.
Deprecated since version 3.12, will be removed in version 3.14: 代わりに
importlib.resources.abc.TraversableResourcesを使ってください。- abstractmethod files()¶
ロードしたパッケージの
importlib.resources.abc.Traversableオブジェクトを返します。
importlib.machinery -- インポータおよびパスフック¶
ソースコード: Lib/importlib/machinery.py
このモジュールには、 import がモジュールを検索してロードするのに役立つ様々なオブジェクトがあります。
- importlib.machinery.SOURCE_SUFFIXES¶
認識されているソースモジュールのファイル接尾辞を表す文字列のリストです。
Added in version 3.3.
- importlib.machinery.DEBUG_BYTECODE_SUFFIXES¶
最適化されていないバイトコードモジュールのファイル接尾辞を表す文字列のリストです。
Added in version 3.3.
バージョン 3.5 で非推奨: 代わりに
BYTECODE_SUFFIXESを使ってください。
- importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES¶
最適化されたバイトコードモジュールのファイル接尾辞を表す文字列のリストです。
Added in version 3.3.
バージョン 3.5 で非推奨: 代わりに
BYTECODE_SUFFIXESを使ってください。
- importlib.machinery.BYTECODE_SUFFIXES¶
認識されているバイトコードモジュールのファイル接尾辞を表す文字列のリストです (先頭のドットを含みます)。
Added in version 3.3.
バージョン 3.5 で変更: この値は
__debug__に依存しなくなりました。
- importlib.machinery.EXTENSION_SUFFIXES¶
認識されている拡張モジュールのファイル接尾辞を表す文字列のリストです。
Added in version 3.3.
- importlib.machinery.all_suffixes()¶
標準のインポート機構によって認識されているすべてのファイル接尾辞を表す文字列の組み合わせられたリストを返します。これが役立つのは、あるファイルシステムパスがモジュールを参照する可能性があるかだけを知りたくて、そのモジュールの種類を詳しく知る必要はないコード (例えば
inspect.getmodulename()) です。Added in version 3.3.
- class importlib.machinery.BuiltinImporter¶
組み込みモジュールの importer です。 すべての既知の組み込みモジュールは
sys.builtin_module_namesに列挙されています。 このクラスはimportlib.abc.MetaPathFinderおよびimportlib.abc.InspectLoader抽象基底クラスを実装します。インスタンス化の必要性を軽減するため、このクラスにはクラスメソッドだけが定義されています。
バージョン 3.5 で変更: As part of PEP 489, the builtin importer now implements
Loader.create_moduleandLoader.exec_module
- class importlib.machinery.FrozenImporter¶
フリーズされたモジュールの インポーター です。このクラスは
importlib.abc.MetaPathFinderおよびimportlib.abc.InspectLoader抽象基底クラスを実装します。インスタンス化の必要性を軽減するため、このクラスにはクラスメソッドだけが定義されています。
バージョン 3.4 で変更: Gained
create_module()andexec_module()methods.
- class importlib.machinery.WindowsRegistryFinder¶
Windows レジストリで宣言されたモジュールの finder です。このクラスは
importlib.abc.MetaPathFinder抽象基底クラスを実装します。インスタンス化の必要性を軽減するため、このクラスにはクラスメソッドだけが定義されています。
Added in version 3.3.
バージョン 3.6 で非推奨: 代わりに
siteの設定を使ってください。 Python の将来のバージョンでは、デフォルトでこのファインダーが使えなくなるかもしれません。
- class importlib.machinery.PathFinder¶
sys.pathおよびパッケージの__path__属性の Finder です。このクラスはimportlib.abc.MetaPathFinder抽象基底クラスを実装します。インスタンス化の必要性を軽減するため、このクラスにはクラスメソッドだけが定義されています。
- classmethod find_spec(fullname, path=None, target=None)¶
sys.pathまたは定義されていれば path から、 fullname で指定されたモジュールの スペック の検索を試みるクラスメソッドです。検索されるそれぞれのパスエントリに対してsys.path_importer_cacheが検査されます。偽でないオブジェクトが見つかれば、それが目的のモジュールを検索するための パスエントリ・ファインダー として使われます。sys.path_importer_cacheに目的のエントリが見つからなければ、パスエントリに対するファインダーがsys.path_hooksから検索され、見つかれば、それがsys.path_importer_cacheに保管されるとともに、モジュールについて問い合わせられます。それでもファインダーが見つからなければNoneが保管され、また返されます。Added in version 3.4.
バージョン 3.5 で変更: もしカレントワーキングディレクトリ -- 空の文字列によって表されている -- がすでに有効でなければ、
Noneが返されますが値はsys.path_importer_cacheにキャッシュされません。
- classmethod invalidate_caches()¶
sys.path_importer_cacheに保存されたファインダーのうち、このメソッドを定義しているすべてのファインダーでimportlib.abc.PathEntryFinder.invalidate_caches()を呼び出します。 一方、sys.path_importer_cacheの値がNoneのエントリーは削除します。バージョン 3.7 で変更:
sys.path_importer_cacheのNoneのエントリーを削除するようになりました。
バージョン 3.4 で変更:
''(すなわち空の文字列) に対してはカレントワーキングディレクトリとともにsys.path_hooksのオブジェクトを呼び出します。
- class importlib.machinery.FileFinder(path, *loader_details)¶
ファイルシステムからの結果をキャッシュする
importlib.abc.PathEntryFinderの具象実装です。path 引数は、このファインダーが検索を担当するディレクトリです。
loader_details 引数は、可変個の 2 要素タプルで、それぞれがローダーとローダーが認識するファイル接尾辞のシーケンスとを含みます。ローダーは、呼び出し可能でモジュール名と見つかったファイルのパスとの 2 引数を受け付けることを期待されます。
ファインダーは必要に応じてディレクトリの内容をキャッシュし、モジュールを検索するたびに stat を呼び出して、キャッシュが古くなっていないか確認します。 キャッシュの古さの判定は、オペレーティングシステムが提供するファイルシステムの状態情報の粒度に依存します。 そのため、モジュールを検索し、新しいファイルを作成し、そのファイルが表すモジュールを検索するという一連の操作では、競合状態が起こる可能性があります。 これらの操作が stat の時間分解能に収まるほど短時間で起こると、モジュールの検索は失敗します。 これを防ぐには、モジュールを動的に作成した際に必ず
importlib.invalidate_caches()を呼び出してください。Added in version 3.3.
- path¶
ファインダーが検索するパスです。
- invalidate_caches()¶
内部キャッシュを完全に消去します。
- classmethod path_hook(*loader_details)¶
sys.path_hooksで使うクロージャを返すクラスメソッドです。 クロージャは、直接渡されたパス引数と、間接的に渡された loader_details を使って、FileFinderインスタンスを返します。クロージャへの引数が存在するディレクトリでなければ、
ImportErrorが送出されます。
- class importlib.machinery.SourceFileLoader(fullname, path)¶
importlib.abc.FileLoaderを継承し、その他いくつかのメソッドの具象実装を提供する、importlib.abc.SourceLoaderの具象実装です。Added in version 3.3.
- name¶
このローダーが扱うモジュールの名前です。
- path¶
ソースファイルへのパスです。
- path_stats(path)¶
- set_data(path, data)¶
- load_module(name=None)¶
ロードするモジュールの名前指定がオプションの、
importlib.abc.Loader.load_module()の具象実装です。Deprecated since version 3.6, will be removed in version 3.15: 代わりに
importlib.abc.Loader.exec_module()を使用してください。
- class importlib.machinery.SourcelessFileLoader(fullname, path)¶
バイトコードファイル (すなわちソースコードファイルが存在しない) をインポートできる
importlib.abc.FileLoaderの具象実装です。注意として、バイトコードを直接使う (つまりソースコードファイルがない) と、そのモジュールはすべての Python 実装では使用できないし、新しいバージョンの Python ではバイトコードフォーマットが変更されていたら使用できません。
Added in version 3.3.
- name¶
ローダーが扱うモジュールの名前です。
- path¶
バイトコードファイルへのパスです。
- get_source(fullname)¶
このローダーを使う場合、バイトコードファイルにはソースがないため
Noneを返します。
- load_module(name=None)¶
ロードするモジュールの名前指定がオプションの、
importlib.abc.Loader.load_module()の具象実装です。Deprecated since version 3.6, will be removed in version 3.15: 代わりに
importlib.abc.Loader.exec_module()を使用してください。
- class importlib.machinery.ExtensionFileLoader(fullname, path)¶
拡張モジュールのための
importlib.abc.ExecutionLoaderの具象実装です。fullname 引数はローダーがサポートするモジュールの名前を指定します。path 引数は拡張モジュールのファイルへのパスです。
複数フェーズの初期化 (PEP 489 を参照) を実装していない拡張モジュールは、通常なら正常にインポートできても、デフォルトではサブインタープリタへのインポートに失敗します。
Added in version 3.3.
バージョン 3.12 で変更: サブインタープリタで使うには、複数フェーズの初期化が必要になりました。
- name¶
ローダーがサポートするモジュールの名前です。
- path¶
拡張モジュールへのパスです。
- is_package(fullname)¶
EXTENSION_SUFFIXESに基づき、ファイルパスがパッケージの__init__モジュールを指す場合にTrueを返します。
- get_code(fullname)¶
拡張モジュールにはコードオブジェクトがないため
Noneを返します。
- get_source(fullname)¶
拡張モジュールにはソースコードがないため
Noneを返します。
- class importlib.machinery.NamespaceLoader(name, path, path_finder)¶
名前空間パッケージ向けの
importlib.abc.InspectLoaderの具体的な実装です。 非公開クラスの別名であり、名前空間パッケージの__loader__属性を調べる目的に限って公開されています。>>> from importlib.machinery import NamespaceLoader >>> import my_namespace >>> isinstance(my_namespace.__loader__, NamespaceLoader) True >>> import importlib.abc >>> isinstance(my_namespace.__loader__, importlib.abc.Loader) True
Added in version 3.11.
- class importlib.machinery.ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)¶
モジュールのインポートシステムに関する状態の仕様です。 通常はモジュールの
__spec__属性として公開されます。 これらの属性の多くはモジュールから直接取得することもでき、例えばmodule.__spec__.origin == module.__file__が成り立ちます。 ただし、通常は 値 が等しくても、2 つのオブジェクト間で同期は行われないため、異なる場合もあります。 例えば、実行時にモジュールの__file__を更新しても、モジュールの__spec__.originには自動的に反映されず、逆も同様です。Added in version 3.4.
- name¶
モジュールの完全修飾名です (
module.__name__を参照)。 ファインダー は、常にこの属性を空でない文字列に設定する必要があります。
- loader¶
モジュールをロードする ローダー です (
module.__loader__を参照)。 ファインダー は常にこの属性を設定する必要があります。
- origin¶
ローダー がモジュールのロードに使う場所です (
module.__file__を参照)。 例えば、.pyファイルからロードするモジュールではファイル名です。 ファインダー は、常に ローダー が使える意味のある値をこの属性に設定する必要があります。 名前空間パッケージなど、該当する場所がない例外的な場合にはNoneに設定してください。
- submodule_search_locations¶
パッケージのサブモジュールを検索する場所を列挙した、文字列の シーケンス です (
module.__path__を参照)。 空の場合もありますが、通常はディレクトリが 1 つだけ含まれます。モジュールがパッケージであることをインポートシステムに示すには、ファインダー は、この属性を空でもよいのでシーケンスに設定する必要があります。 パッケージでないモジュールでは
Noneにしてください。 名前空間パッケージでは、後で特殊なオブジェクトが自動的に設定されます。
- cached¶
The filename of a compiled version of the module's code (see
module.__cached__). The finder should always set this attribute but it may beNonefor modules that do not need compiled code stored.
- parent¶
(読み取り専用) モジュールが属するパッケージの完全修飾名です (トップレベルのモジュールでは空文字列)。
module.__package__を参照してください。 モジュール自体がパッケージであれば、nameと同じです。
- class importlib.machinery.AppleFrameworkLoader(name, path)¶
フレームワーク形式の拡張モジュールを読み込み事ができる、特殊な
importlib.machinery.ExtensionFileLoaderです。iOS App Store との互換性のため、 iOS アプリの すべての バイナリモジュールは、パッケージ化されたアプリの
Frameworksフォルダーに保存された、適切なメタデータ付きのフレームワークにある動的ライブラリである必要があります。フレームワークごとにバイナリは一つだけで、 Frameworks フォルダーの外に実行可能バイナリデータを設置することはできません。To accommodate this requirement, when running on iOS, extension module binaries are not packaged as
.sofiles onsys.path, but as individual standalone frameworks. To discover those frameworks, this loader is registered against the.fworkfile extension, with a.fworkfile acting as a placeholder in the original location of the binary onsys.path. The.fworkfile contains the path of the actual binary in theFrameworksfolder, relative to the app bundle. To allow for resolving a framework-packaged binary back to the original location, the framework is expected to contain a.originfile that contains the location of the.fworkfile, relative to the app bundle.例えば、
from foo.bar import _whizをインポートする場合を考えてみましょう。_whizがバイナリモジュールsources/foo/bar/_whiz.abi3.soで実装されており、sourcesのアプリケーションバンドルからの相対パスがsys.pathに登録されています。このモジュールはFrameworks/foo.bar._whiz.framework/foo.bar._whiz(フレームワーク名はモジュールの完全なインポートパスから命名されています) として、バイナリをフレームワークとして識別するInfo.plistファイルを.frameworkディレクトリ内に設置して配布しなければなりません。foo.bar._whizモジュールは、元の場所で、Frameworks/foo.bar._whiz/foo.bar._whizのパスを含むsources/foo/bar/_whiz.abi3.fworkマーカーファイルに記述されます。 また、フレームワークは、.fworkへのパスを含むFrameworks/foo.bar._whiz.framework/foo.bar._whiz.originも含まなければなりません。When a module is loaded with this loader, the
__file__for the module will report as the location of the.fworkfile. This allows code to use the__file__of a module as an anchor for file system traveral. However, the spec origin will reference the location of the actual binary in the.frameworkfolder.PYTHONPATH内のどこにある.soファイルも、Frameworksフォルダ内のフレームワークに変換し、.fworkと.originファイルを作成する責任は、アプリをビルドする Xcode プロジェクトにあります。 変換には、モジュールファイルの拡張子の除去、フレームワークのメタデータの追加、生成されたフレームワークへの署名も含まれます。 通常は Xcode プロジェクトのビルドステップで行います。 このビルドステップの作成方法は iOS のドキュメントを参照してください。Added in version 3.13.
利用可能な環境: iOS.
- name¶
ローダーがサポートするモジュールの名前です。
- path¶
拡張モジュールの
.fworkファイルへのパス。
importlib.util -- インポータのためのユーティリティコード¶
ソースコード: Lib/importlib/util.py
このモジュールには、 インポーター の構築を助ける様々なオブジェクトがあります。
- importlib.util.MAGIC_NUMBER¶
バイトコードバージョン番号を表しているバイト列。バイトコードのロード/書き込みについてヘルプが必要なら
importlib.abc.SourceLoaderを参照してください。Added in version 3.4.
- importlib.util.cache_from_source(path, debug_override=None, *, optimization=None)¶
Return the PEP 3147/PEP 488 path to the byte-compiled file associated with the source path. For example, if path is
/foo/bar/baz.pythe return value would be/foo/bar/__pycache__/baz.cpython-32.pycfor Python 3.2. Thecpython-32string comes from the current magic tag (seesys.implementation.cache_tag; if it is not defined thenNotImplementedErrorwill be raised).optimization パラメータは、バイトコードファイルの最適化レベルを指定するために使われます。空文字列は最適化しないことを表します。したがって、 optimization が
''のとき/foo/bar/baz.pyに対して/foo/bar/__pycache__/baz.cpython-32.pycというバイトコードパスが返ります。Noneにするとインタープリタの最適化レベルが使われます。それ以外では値の文字列表現が使われます。したがって、 optimization が2のとき/foo/bar/baz.pyに対して/foo/bar/__pycache__/baz.cpython-32.opt-2.pycというバイトコードパスが返ります。 optimization の文字列表現は英数字だけが可能で、そうでなければValueErrorが上げられます。debug_override パラメータは deprecated で、システムの
__debug__値をオーバーライドするために使用できます。True値は optimization を空文字列に設定するのと等価です。False値は optimization を1に設定するのと同等です。もし debug_override と optimization のどちらもNone以外であればTypeErrorが上げられます。Added in version 3.4.
バージョン 3.5 で変更: optimization パラメータが追加され、 debug_override パラメータは deprecated になりました。
バージョン 3.6 で変更: path-like object を受け入れるようになりました。
- importlib.util.source_from_cache(path)¶
Given the path to a PEP 3147 file name, return the associated source code file path. For example, if path is
/foo/bar/__pycache__/baz.cpython-32.pycthe returned path would be/foo/bar/baz.py. path need not exist, however if it does not conform to PEP 3147 or PEP 488 format, aValueErroris raised. Ifsys.implementation.cache_tagis not defined,NotImplementedErroris raised.Added in version 3.4.
バージョン 3.6 で変更: path-like object を受け入れるようになりました。
- importlib.util.decode_source(source_bytes)¶
与えられたソースコードを表すバイト列をデコードして、文字列としてそれを一般的な改行形式 (universal newlines) で返します (
importlib.abc.InspectLoader.get_source()で要求されるように)。Added in version 3.4.
- importlib.util.resolve_name(name, package)¶
相対的なモジュール名を解決して絶対的なものにします。
name の先頭にドットがなければ、単に name が返されます。これにより、例えば
importlib.util.resolve_name('sys', __spec__.parent)を使うときに package 変数が必要かどうかを確認する必要がなくなります。name が相対的なモジュール名であるにもかかわらず package が偽値 (例えば
Noneや空文字列) ならば、ImportErrorが送出されます。相対的な名前がそれを含むパッケージから抜け出る (例えばspamパッケージ内から..baconを要求する) 場合にもImportErrorが送出されます。Added in version 3.3.
バージョン 3.9 で変更: インポート文との一貫性を高めるため、不正な相対インポートに対して
ValueErrorではなくImportErrorを送出するようになりました。
- importlib.util.find_spec(name, package=None)¶
モジュールの スペック を検索します。 必要に応じて、指定した package 名を基準にした相対名を使えます。 モジュールが
sys.modulesにあれば、sys.modules[name].__spec__を返します (ただし、スペックがNoneか未設定の場合はValueErrorを送出します)。 それ以外の場合はsys.meta_pathを使って検索します。 スペックが見つからなければNoneを返します。name がサブモジュールを示している (ドットを含む) 場合、親モジュールは自動的にインポートされます。
name and package work the same as for
importlib.import_module().Added in version 3.4.
バージョン 3.7 で変更: package が実際にはパッケージでない (
__path__属性がない) 場合、AttributeErrorではなくModuleNotFoundErrorを送出するようになりました。
- importlib.util.module_from_spec(spec)¶
spec と
spec.loader.create_moduleに基づいて新しいモジュールを作ります。spec.loader.create_moduleがNoneを返さない場合は、既に存在するどの属性もリセットされません。また、 spec にアクセスしたり属性をモジュールに設定したりする際にAttributeError例外が起きても例外は送出されません。この関数は、新しいモジュールを作る方法として
types.ModuleTypeよりも推奨されます。なぜなら、できるだけ多くのインポートコントロールされた属性をモジュールに設定するために spec が使用されるからです。Added in version 3.5.
- importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None)¶
A factory function for creating a
ModuleSpecinstance based on a loader. The parameters have the same meaning as they do for ModuleSpec. The function uses available loader APIs, such asInspectLoader.is_package, to fill in any missing information on the spec.Added in version 3.4.
- importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)¶
ファイルへのパスにもとづいて
ModuleSpecインスタンスを生成するためのファクトリー関数。不足している情報は、ローダー API を利用してスペックから得られる情報と、モジュールがファイルベースであるという暗黙的な情報によって埋められます。Added in version 3.4.
バージョン 3.6 で変更: path-like object を受け入れるようになりました。
- importlib.util.source_hash(source_bytes)¶
source_bytes のハッシュをバイト列として返します。 ハッシュベースの
.pycファイルは、対応するソースファイルの内容のsource_hash()をヘッダに埋め込みます。Added in version 3.7.
- importlib.util._incompatible_extension_module_restrictions(*, disable_check)¶
拡張モジュールの互換性チェックを一時的に省略できるコンテキストマネージャです。 デフォルトではチェックが有効で、単一フェーズの初期化を使うモジュールをサブインタープリタにインポートすると失敗します。 また、複数フェーズの初期化を使うモジュールでも、インタープリタごとの GIL を明示的にサポートしていなければ、独自の GIL を持つインタープリタへのインポートは失敗します。
この関数は特殊なケースに対応するためのものであり、そのケースも将来なくなる可能性があります。 探していた機能とは違う可能性が高いことに注意してください。
複数フェーズの初期化 (PEP 489) の基本インターフェースを実装し、複数インタープリタ (またはインタープリタごとの GIL) のサポートを偽って申告することでも、この関数と同じ効果を得られます。
警告
この関数でチェックを無効にすると、予期しない動作やクラッシュさえ引き起こす場合があります。 拡張モジュールの開発中に限って使ってください。
Added in version 3.12.
- class importlib.util.LazyLoader(loader)¶
モジュールの属性がアクセスされるまで、そのモジュールのローダーの実行を遅延するクラスです。
このクラスは、モジュールに使う型を制御する必要があるため、
exec_module()を定義したローダーで のみ 動作します。 同じ理由で、ローダーのcreate_module()メソッドは、Noneか、__class__属性を変更でき、かつ スロット を使わない型のオブジェクトを返す必要があります。 また、sys.modulesに置いたオブジェクトを別のオブジェクトに差し替えるモジュールでは動作しません。 インタープリタ全体のモジュールへの参照を安全かつ正しく置き換える方法がないためです。 このような差し替えを検出するとValueErrorを送出します。注釈
起動時間が重要なプロジェクトでは、もし決して使われないモジュールがあれば、このクラスを使ってモジュールをロードするコストを最小化できるかもしれません。スタートアップ時間が重要でないプロジェクトでは、遅延されたロードの際に発生して文脈の外で起こるエラーメッセージのため、このクラスの使用は 著しく 推奨されません。
Added in version 3.5.
バージョン 3.6 で変更:
create_module()を呼び出すようになり、importlib.machinery.BuiltinImporterとimportlib.machinery.ExtensionFileLoaderに対する互換性の警告を削除しました。- classmethod factory(loader)¶
遅延ローダを生成する callable を返すクラスメソッド。これは、ローダーをインスタンスとしてではなくクラスとして渡すような状況において使われることを意図しています。
suffixes = importlib.machinery.SOURCE_SUFFIXES loader = importlib.machinery.SourceFileLoader lazy_loader = importlib.util.LazyLoader.factory(loader) finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
使用例¶
プログラムからのインポート¶
プログラムからモジュールをインポートするには、 importlib.import_module() を使ってください。
import importlib
itertools = importlib.import_module('itertools')
モジュールがインポートできるか確認する¶
インポートを実際に行わずに、あるモジュールがインポートできるかを知る必要がある場合は、 importlib.util.find_spec() を使ってください。
name がサブモジュールを指す (ドットを含む) 場合、importlib.util.find_spec() は親モジュールをインポートします。
import importlib.util
import sys
# 説明のための例。
name = 'itertools'
if name in sys.modules:
print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
# 実際にインポートする場合...
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
print(f"{name!r} has been imported")
else:
print(f"can't find the {name!r} module")
ソースファイルから直接インポートする¶
この方法は注意して使ってください。
sys.path を検索する代わりにファイルパスを直接指定し、インポート文に近い動作をするものです。
まずは、正式なモジュールが必要なら sys.path を変更する、Python ファイルを実行した結果のグローバル名前空間でよければ runpy.run_path() を使うなど、別の方法を検討してください。
パスから Python ソースファイルを直接インポートするには、次のようにします。
import importlib.util
import sys
def import_from_path(module_name, file_path):
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
return module
# 説明のための例にすぎない (`json` を選んだことに特別な意味はない)。
import json
file_path = json.__file__
module_name = json.__name__
# `import json` と同様の結果。
json = import_from_path(module_name, file_path)
遅延インポートの実装¶
以下の例は遅延インポートを実装する方法を示します。
>>> import importlib.util
>>> import sys
>>> def lazy_import(name):
... spec = importlib.util.find_spec(name)
... loader = importlib.util.LazyLoader(spec.loader)
... spec.loader = loader
... module = importlib.util.module_from_spec(spec)
... sys.modules[name] = module
... loader.exec_module(module)
... return module
...
>>> lazy_typing = lazy_import("typing")
>>> #lazy_typing は実際のモジュールオブジェクトだが、
>>> #まだメモリにロードされていない。
>>> lazy_typing.TYPE_CHECKING
False
インポーターのセットアップ¶
インポートを大幅にカスタマイズする場合、通常は インポーター を実装します。
そのためには、ファインダー と ローダー の両方を扱います。
ファインダーには メタパスファインダー と パスエントリファインダー の 2 種類があり、必要に応じて選べます。
前者は sys.meta_path に登録するものです。
後者は sys.path_hooks にある パスエントリフック が sys.path の各要素に対して処理し、必要に応じて作成するものです。
この例では、独自のインポーターをインポート時に使わせるために登録する方法を示します (インポーター自体の作成方法は、このパッケージで定義された適切なクラスのドキュメントを読んでください)。
import importlib.machinery
import sys
# 説明のための例。
SpamMetaPathFinder = importlib.machinery.PathFinder
SpamPathEntryFinder = importlib.machinery.FileFinder
loader_details = (importlib.machinery.SourceFileLoader,
importlib.machinery.SOURCE_SUFFIXES)
# メタパスファインダーを設定する。
# 優先順位に応じて、リスト内の適切な位置にファインダーを登録する。
sys.meta_path.append(SpamMetaPathFinder)
# パスエントリファインダーを設定する。
# 優先順位に応じて、リスト内の適切な位置にパスフックを登録する。
sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))
importlib.import_module() に近い実装¶
インポート自体が Python コードで実装されているため、インポート機構の大部分を importlib を通じて公開できます。
以下では importlib.import_module() に近い実装を示し、importlib が公開するさまざまな API の使い方を説明します。
import importlib.util
import sys
def import_module(name, package=None):
"""インポートに近い動作をする実装。"""
absolute_name = importlib.util.resolve_name(name, package)
try:
return sys.modules[absolute_name]
except KeyError:
pass
path = None
if '.' in absolute_name:
parent_name, _, child_name = absolute_name.rpartition('.')
parent_module = import_module(parent_name)
path = parent_module.__spec__.submodule_search_locations
for finder in sys.meta_path:
spec = finder.find_spec(absolute_name, path)
if spec is not None:
break
else:
msg = f'No module named {absolute_name!r}'
raise ModuleNotFoundError(msg, name=absolute_name)
module = importlib.util.module_from_spec(spec)
sys.modules[absolute_name] = module
spec.loader.exec_module(module)
if path is not None:
setattr(parent_module, child_name, module)
return module