top of page

The import

  • Writer: VC Healy
    VC Healy
  • May 24, 2020
  • 3 min read

Import-related module attributes The import machinery fills in these attributes on each module object during loading, based on the module’s spec, before the loader executes the module. __name__

The __name__ attribute must be set to the fully-qualified name of the module. This name is used to uniquely identify the module in the import system.


__loader__

The __loader__ attribute must be set to the loader object that the import machinery used when loading the module. This is mostly for introspection, but can be used for additional loader-specific functionality, for example getting data associated with a loader.


__package__

The module’s __package__ attribute must be set. Its value must be a string, but it can be the same value as its __name__. When the module is a package, its __package__ value should be set to its __name__. When the module is not a package, __package__ should be set to the empty string for top-level modules, or for submodules, to the parent package’s name.

This attribute is used instead of __name__ to calculate explicit relative imports for main modules, as defined in PEP 366.

It is expected to have the same value as __spec__.parent. Changed in version 3.6: The value of __package__ is expected to be the same as __spec__.parent.


__spec__

The __spec__ attribute must be set to the module spec that was used when importing the module. Setting __spec__ appropriately applies equally to modules initialized during interpreter startup. The one exception is __main__, where __spec__ is set to None in some cases. When __package__ is not defined, __spec__.parent is used as a fallback. New in version 3.4. Changed in version 3.6: __spec__.parent is used as a fallback when __package__ is not defined.


__path__

If the module is a package (either regular or namespace), the module object’s __path__ attribute must be set. The value must be iterable, but may be empty if __path__ has no further significance. If __path__ is not empty, it must produce strings when iterated over. More details on the semantics of __path__ are given below. Non-package modules should not have a __path__ attribute.


__file__

__cached__

__file__ is optional. If set, this attribute’s value must be a string. The import system may opt to leave __file__ unset if it has no semantic meaning (e.g. a module loaded from a database).

If __file__ is set, it may also be appropriate to set the __cached__ attribute which is the path to any compiled version of the code (e.g. byte-compiled file). The file does not need to exist to set this attribute; the path can simply point to where the compiled file would exist

It is also appropriate to set __cached__ when __file__ is not set. However, that scenario is quite atypical. Ultimately, the loader is what makes use of __file__ and/or __cached__. So if a loader can load from a cached module but otherwise does not load from a file, that atypical scenario may be appropriate.


module.__path__ By definition, if a module has a __path__ attribute, it is a package. A package’s __path__ attribute is used during imports of its subpackages. Within the import machinery, it functions much the same as sys.path, i.e. providing a list of locations to search for modules during import. However, __path__ is typically much more constrained than sys.path. __path__ must be an iterable of strings, but it may be empty. The same rules used for sys.path also apply to a package’s __path__, and sys.path_hooks (described below) are consulted when traversing a package’s __path__.

A package’s __init__.py file may set or alter the package’s __path__ attribute, and this was typically the way namespace packages were implemented prior to PEP 420. With the adoption of PEP 420, namespace packages no longer need to supply __init__.py files containing only __path__ manipulation code; the import machinery automatically sets __path__ correctly for the namespace package.


The import statement

The most common way to invoke the import machinery. Other related functions importlib.import_module() and built-in __import__()


import combines two operations.

Search for named module

# import calls __import__() for this with the appropriate parameters


Bind the result of the search name to a name in the local scope.


Direct calling of __import__ only performs the search and module creation operation.

There can be issues with this action as only import performs the binding operation.


If the named module cannot be found a ModuleNotFoundError is raised


import *

This will at first glance be thought to import all the functions from another module/package.


What it doesn't do, is import any fnction that's name starts with an _. This is the system of naming that allows Python to mark functions as private/local to that module. Thus these would not be imported.


There is a secondary attribute held in the module being imported that with explicitly limit the functions that can be exported by an import *.

__all__ statements can be drawn up at the top of the exporting module assigning a list with elements that are function names from the module that are allowed to be exported. Thus making all functions in that module private unless detailed in that list.

 
 
 

Σχόλια


© 2020 by Vincent Healy. Proudly created with Wix.com

bottom of page