[Tutor] creating import directories

Steven D'Aprano steve at pearwood.info
Sun May 19 07:19:24 CEST 2013


On 19/05/13 14:08, Jim Mooney wrote:
> I'm a bit unclear about creating import directories.

The terminology you want here is "import packages". You cannot import directories. You can only import modules and packages.

"Module" in Python has two meanings:

1) a module is a file containing Python code, such as:

- source code in a .py file

- pre-compiled byte code in a .pyc file

- C libraries in a .dll or .so file

- and various others.

2) a module is an object that exists in memory, created by Python when you import a module as defined above, *or* a package as defined below.


A package, on the other hand, is a way of collecting multiple modules (definition 1 above) into a single directory, so that it becomes a self-contained group of files. The way to do this is by setting up the directory in a way that Python understands as a package:


1) The directory must be somewhere that Python will see it, no different from a single file module. That means, in the current directory, or your PYTHONPATH.

2) The directory name must be legal as a module name. That means, it must follow the same rules as names for modules, except without the .py extension.

"mymodule" is good
"my module" (note space) is bad

3) Inside the module, you MUST put in a special file called "__init__.py" for Python to recognise it as a package. This is critical. This file can be empty, or it can contain Python code, but it must exist.

4) Any other modules inside the package follow the usual naming rules.

5) Last, and optional, if you want to run the package as if it were a script, you give it a file called "__main__.py" containing the code to run.

So, if I create the following directory structure where Python can see it:


mypackage/
   +-- __init__.py
   +-- spam.py
   +-- eggs.py
   +-- math.py


then I can do this:

import mypackage

which will read the file mypackage/__init__.py and create a module object (definition 2 above) called "mypackage".


import mypackage.spam

will *first* read mypackage/__init__.py (if it hasn't already read it), and *then* read mypackage/spam.py. Once this has done, you can use:

result = mypackage.spam.function()

to call the function inside the spam module.

Similarly for mypackage.eggs and mypackage.math, which is especially interesting because it means you don't have to worry about your package's math.py module shadowing (hiding) the standard math module that Python uses.

You can learn more about packages from this historical document:

http://www.python.org/doc/essays/packages.html

Even though this goes back to the Dark Ages of Python 1.3 (!) most of the details of packages have not changed.


One more trick: starting from Python 2.7, or optionally in 2.5 and 2.6, there is a special form of the import statement that tells Python to only look inside the *current* package. If I write

import math

inside (say) mypackage.spam, I will get the standard math module. But if I write:

from . import math

I will get the custom math module inside the package. I can even get them both at the same time, with a bit of renaming:

import math
from . import math as mymaths

Google on "absolute and relative imports" for more information on that.



> Also, I noticed Wing 101 is sometimes creating a same-named pyc
> program alongside my py program, but I don't see an option to do that.


This is normal behaviour when you import a module.

When you import a module, Python performs two versions of caching:

import spam


will first look in sys.modules for an entry called "spam", and if found, it will use that. If there is no such entry, Python looks for a .py file called "spam". If it finds one, it compiles it to byte code. To speed up that process for the next time, it caches that byte code in the a file called spam.pyc.

Of course Python also checks the timestamps on the source file, and won't use old byte code when the source code has changed.

This only occurs when you import a module. Just running the module will not cache the byte code.



-- 
Steven


More information about the Tutor mailing list