The Python import
has a major feature in that it ties two things together -- how to find the import and under what namespace to include it.
This creates very explicit code:
import xml.sax
This specifies where to find the code we want to use, by the rules of the Python search path.
At the same time, all objects that we want to access live under this exact namespace, for example xml.sax.ContentHandler
.
I regard this as an advantage to Ruby's require. require 'xml'
might in fact make objects inside the namespace XML
or any other namespace available in the module, without this being directly evident from the require line.
If xml.sax.ContentHandler
is too long, you may specify a different name when importing:
import xml.sax as X
And it is now avalable under X.ContentHandler
.
This way Python requires you to explicitly build the namespace of each module. Python namespaces are thus very "physical", and I'll explain what I mean:
- By default, only names directly defined in the module are available in its namespace: functions, classes and so.
- To add to a module's namespace, you explicitly import the names you wish to add, placing them (by reference) "physically" in the current module.
For example, if we have the small Python package "process" with internal submodules machine
and interface
, and we wish to present this as one convenient namespace directly under the package name, this is and example of what we could write in the "package definition" file process/__init__.py
:
from process.interface import *
from process.machine import Machine, HelperMachine
Thus we lift up what would normally be accessible as process.machine.Machine
up to process.Machine
. And we add all names from process.interface
to process
namespace, in a very explicit fashion.
The advantages of Python's import that I wrote about were simply two:
- Clear what you include when using
import
- Explicit how you modify your own module's namespace (for the program or for others to import)