mirror of https://github.com/python/cpython
Issue #25802: Add an examples section to importlib.
Thanks to Berker Peksag for the patch review.
This commit is contained in:
parent
fd65958f4f
commit
a85e927e39
|
@ -81,7 +81,9 @@ This module provides an interface to the mechanisms used to implement the
|
|||
.. deprecated:: 3.3
|
||||
Use :func:`importlib.util.find_spec` instead unless Python 3.3
|
||||
compatibility is required, in which case use
|
||||
:func:`importlib.find_loader`.
|
||||
:func:`importlib.find_loader`. For example usage of the former case,
|
||||
see the :ref:`importlib-examples` section of the :mod:`importlib`
|
||||
documentation.
|
||||
|
||||
|
||||
.. function:: load_module(name, file, pathname, description)
|
||||
|
@ -108,9 +110,12 @@ This module provides an interface to the mechanisms used to implement the
|
|||
If previously used in conjunction with :func:`imp.find_module` then
|
||||
consider using :func:`importlib.import_module`, otherwise use the loader
|
||||
returned by the replacement you chose for :func:`imp.find_module`. If you
|
||||
called :func:`imp.load_module` and related functions directly then use the
|
||||
classes in :mod:`importlib.machinery`, e.g.
|
||||
``importlib.machinery.SourceFileLoader(name, path).load_module()``.
|
||||
called :func:`imp.load_module` and related functions directly with file
|
||||
path arguments then use a combination of
|
||||
:func:`importlib.util.spec_from_file_location` and
|
||||
:func:`importlib.util.module_from_spec`. See the :ref:`importlib-examples`
|
||||
section of the :mod:`importlib` documentation for details of the various
|
||||
approaches.
|
||||
|
||||
|
||||
.. function:: new_module(name)
|
||||
|
@ -119,7 +124,7 @@ This module provides an interface to the mechanisms used to implement the
|
|||
in ``sys.modules``.
|
||||
|
||||
.. deprecated:: 3.4
|
||||
Use :class:`types.ModuleType` instead.
|
||||
Use :func:`importlib.util.module_from_spec` instead.
|
||||
|
||||
|
||||
.. function:: reload(module)
|
||||
|
|
|
@ -256,7 +256,7 @@ ABC hierarchy::
|
|||
module and *path* will be the value of :attr:`__path__` from the
|
||||
parent package. If a spec cannot be found, ``None`` is returned.
|
||||
When passed in, ``target`` is a module object that the finder may
|
||||
use to make a more educated about what spec to return.
|
||||
use to make a more educated guess about what spec to return.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
|
@ -306,7 +306,7 @@ ABC hierarchy::
|
|||
within the :term:`path entry` to which it is assigned. If a spec
|
||||
cannot be found, ``None`` is returned. When passed in, ``target``
|
||||
is a module object that the finder may use to make a more educated
|
||||
about what spec to return.
|
||||
guess about what spec to return.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
|
||||
|
@ -1307,3 +1307,90 @@ an :term:`importer`.
|
|||
loader = importlib.machinery.SourceFileLoader
|
||||
lazy_loader = importlib.util.LazyLoader.factory(loader)
|
||||
finder = importlib.machinery.FileFinder(path, [(lazy_loader, suffixes)])
|
||||
|
||||
.. _importlib-examples:
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To programmatically import a module, use :func:`importlib.import_module`.
|
||||
::
|
||||
|
||||
import importlib
|
||||
|
||||
itertools = importlib.import_module('itertools')
|
||||
|
||||
If you need to find out if a module can be imported without actually doing the
|
||||
import, then you should use :func:`importlib.util.find_spec`.
|
||||
::
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
|
||||
# For illustrative purposes.
|
||||
name = 'itertools'
|
||||
|
||||
spec = importlib.util.find_spec(name)
|
||||
if spec is None:
|
||||
print("can't find the itertools module")
|
||||
else:
|
||||
# If you chose to perform the actual import.
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
# Adding the module to sys.modules is optional.
|
||||
sys.modules[name] = module
|
||||
|
||||
To import a Python source file directly, use the following recipe
|
||||
(Python 3.4 and newer only)::
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
|
||||
# For illustrative purposes.
|
||||
import tokenize
|
||||
file_path = tokenize.__file__
|
||||
module_name = tokenize.__name__
|
||||
|
||||
spec = importlib.util.spec_from_file_location(module_name, file_path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
# Optional; only necessary if you want to be able to import the module
|
||||
# by name later.
|
||||
sys.modules[module_name] = module
|
||||
|
||||
Import itself is implemented in Python code, making it possible to
|
||||
expose most of the import machinery through importlib. The following
|
||||
helps illustrate the various APIs that importlib exposes by providing an
|
||||
approximate implementation of
|
||||
:func:`importlib.import_module` (Python 3.4 and newer for importlib usage,
|
||||
Python 3.6 and newer for other parts of the code).
|
||||
::
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
|
||||
def import_module(name, package=None):
|
||||
"""An approximate implementation of import."""
|
||||
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:
|
||||
raise ImportError(f'No module named {absolute_name!r}')
|
||||
module = spec.loader.create_module(spec)
|
||||
spec.loader.exec_module(module)
|
||||
sys.modules[absolute_name] = module
|
||||
if path is not None:
|
||||
setattr(parent_module, child_name, module)
|
||||
return module
|
||||
|
|
Loading…
Reference in New Issue