17.2 Package Import Example
Let's actually code the example
we've been talking about to show how initialization
files and paths come into play. The following three files are coded
in a directory dir1 and its subdirectory
dir2:
#File: dir1\__init__.py
print 'dir1 init'
x = 1
#File: dir1\dir2\__init__.py
print 'dir2 init'
y = 2
#File: dir1\dir2\mod.py
print 'in mod.py'
z = 3
Here, dir1 will either be a subdirectory of the
one we're working in (i.e., the home directory), or
a subdirectory of a directory that is listed on the module search
path (technically, on sys.path). Either way,
dir1's container does not need an
__init__.py file.
As for simple module files, import statements run each
directory's initialization file as Python descends
the path, the first time a directory is traversed;
we've added print statements to
trace their execution. Also like module files, already-imported
directories may be passed to reload to force
re-execution of that single item—reload accepts a dotted path
name to reload nested directories and files:
% python
>>> import dir1.dir2.mod # First imports run init files.
dir1 init
dir2 init
in mod.py
>>>
>>> import dir1.dir2.mod # Later imports do not.
>>>
>>> reload(dir1)
dir1 init
<module 'dir1' from 'dir1\__init__.pyc'>
>>>
>>> reload(dir1.dir2)
dir2 init
<module 'dir1.dir2' from 'dir1\dir2\__init__.pyc'>
Once imported, the path in your import statement
becomes a nested object path in your script;
mod is an object nested in object
dir2, nested in object dir1:
>>> dir1
<module 'dir1' from 'dir1\__init__.pyc'>
>>> dir1.dir2
<module 'dir1.dir2' from 'dir1\dir2\__init__.pyc'>
>>> dir1.dir2.mod
<module 'dir1.dir2.mod' from 'dir1\dir2\mod.pyc'>
In fact, each directory name in the path becomes a variable, assigned
to a module object whose namespace is initialized by all the
assignments in that directory's __init__.py file. dir1.x refers to the
variable x assigned in dir1\__init__.py, much as mod.z refers to
z assigned in mod.py:
>>> dir1.x
1
>>> dir1.dir2.y
2
>>> dir1.dir2.mod.z
3
17.2.1 from Versus import with Packages
import statements can be
somewhat inconvenient to use with packages, because you must retype
paths frequently in your program. In the prior
section's example, you must retype and rerun the
full path from dir1 each time you want to reach
z. In fact, we get errors here if we try to access
dir2 or mod directly at this
point.
>>> dir2.mod
NameError: name 'dir2' is not defined
>>> mod.z
NameError: name 'mod' is not defined
Because of that, it's often more convenient to use
the from statement with packages, to avoid
retyping paths at each access. Perhaps more importantly, if you ever
restructure your directory tree, the from
statement requires just one path update in your code, whereas the
import may require many. The import
as extension, discussed in the next chapter, can also help
here, by providing a shorter synonym for the full path:
% python
>>> from dir1.dir2 import mod # Code the path here only.
dir1 init
dir2 init
in mod.py
>>> mod.z # Don't repeat path.
3
>>> from dir1.dir2.mod import z
>>> z
3
>>> import dir1.dir2.mod as mod # Use shorter name.
>>> mod.z
3
|