I had never noticed the __path__ attribute that gets defined on some of my packages before today. According to the documentation:
Packages support one more special
attribute,__path__. This is
initialized to be a list containing
the name of the directory holding the
package’s__init__.pybefore the code
in that file is executed. This
variable can be modified; doing so
affects future searches for modules
and subpackages contained in the
package.While this feature is not often
needed, it can be used to extend the
set of modules found in a package.
Could somebody explain to me what exactly this means and why I would ever want to use it?
This is usually used with pkgutil to let a package be laid out across the disk. E.g., zope.interface and zope.schema are separate distributions (
zopeis a “namespace package”). You might have zope.interface installed in/usr/lib/python2.6/site-packages/zope/interface/, while you are using zope.schema more locally in/home/me/src/myproject/lib/python2.6/site-packages/zope/schema.If you put
pkgutil.extend_path(__path__, __name__)in/usr/lib/python2.6/site-packages/zope/__init__.pythen both zope.interface and zope.schema will be importable because pkgutil will have change__path__to['/usr/lib/python2.6/site-packages/zope', '/home/me/src/myproject/lib/python2.6/site-packages/zope'].pkg_resources.declare_namespace(part of Setuptools) is likepkgutil.extend_pathbut is more aware of zips on the path.Manually changing
__path__is uncommon and probably not necessary, though it is useful to look at the variable when debugging import problems with namespace packages.You can also use
__path__for monkeypatching, e.g., I have monkeypatched distutils at times by creating a filedistutils/__init__.pythat is early onsys.path: