Python Importing

This post is a few years old now, so some details (or my opinions) might be out of date.
I would still love to hear your feedback in the comments below. Enjoy!

When you start to work on even rudimentary Python application, the first thing you usually do is import some package you’re using. There are many ways to import packages and modules - some are extremely common (found in pretty much every Python file ever written) and some less so. In this post I will cover different ways to import or reload modules, some conventions regarding importing, import loops and some import easter-eggs you can find in Python.

Cheat Sheet

import foo
import foo.bar
from foo import bar
from foo import bar, baz
from foo import *
from foo import bar as fizz
from .foo import bar
foo = __import__("foo")
reload(foo)

Different Ways to Import

1. import foo

The basic Python import. The statement import foo looks for a foo model, loads it into memory and creates a module object called foo. How does Python knows where to find the foo module?

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • the directory containing the input script (or the current directory).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • the installation-dependent default.

(from the documentation)

If there is a bar object (which could be anything from a function to a submodule) it can be accessed like a member: foo.bar. You can also import several modules in one line by doing import foo, bar, but it is considered good practice to put each import in a single line.

2. import foo.bar

This makes foo.bar available without importing other stuff from foo. The difference from import foo is that if foo also had a baz member, it won’t be accessible.

3. from foo import bar

This statement imports bar which could be anything that is declared in the module. It could be a function definition, a class (albeit a not-conventionally-named class) or even a submodule (which make foo a package). Notice that if bar is a submodule of foo, this statement acts as if we simply imported bar (if it was in Python’s search path). This means that a bar object is created, and its type is 'module'. No foo object is created in this statement.

Multiple members of foo can be imported in the same line like so:

4. from foo import bar, baz

The meaning of this is pretty intuitive: it imports both bar and baz from the module foo. bar and baz aren’t neccessarily the same types: baz could be a submodule and bar could be function, for that matter. Unlike importing unrelated modules, it’s perfectly acceptable to import everything from one module in the same line.

5. from foo import *

Sometimes foo contains so many things, that it becomes cumbersome to import them manually. Instead, you can just import * to import them all at the same time. Don’t do this unless you know what you’re doing! It may seem convenient to just import * instead of specific members, but it is considered bad practice. The reason is that you are in fact “contaminating” your global namespace. Imagine that you do import * on a package where someone unwittingly declared the following function:

def list():
    raise RuntimeError("I'm rubber, you're glue!")

When you do import *, this list definition will override the global, built-in list type and you’ll get very, very unexpected errors. So it’s always better to know exactly what you’re importing. If you’re importing too much stuff from a certain package, you can either just suck it up or just import the package itself (import foo) and use the foo qualifier for every use. An interesting good use for import * is in Django settings file hierarchy. It’s convenient there because you actually do want to manipulate the global namespace with imported settings.

6. from foo import bar as fizz

This one is far less common than what we covered so far, but still well known. It acts like from foo import bar, except instead of creating a bar object, it creates a fizz module with the same meaning. There are two main reasons to use this kind of statement: the first is when you’re importing two similarly named objects from two different modules. You then use import as to differentiate them, like so:

from xml import Parser as XmlParser 
from json import Parser as JsonParser

The other reason, which I’ve seen used a few times is when you import a lone-named function (or class) and use it extensively throughout your code and want to shorten its name.

7. from .foo import bar

Well, this escalated quickly.

This one is pretty rare and a lot of people are completely unaware of it. The only difference in this statement is that it uses a modified search path for modules. Namely, instead of searching the entire PYTHONPATH, it searches in the directory where the importing file lives. So if you have two files called fizz.py and foo.py, you can use this import in fizz, and it will import the correct file, even if you have another foo module in your PYTHONPATH. What is this good for? Well, sometime you create modules with generic names like common, but you might also have a common package in the base of your project. Instead of giving different names, you can explicitly import the one closest to you. You can also use this method to load modules from an ancestor in the directory tree by putting several dots. For example, from ..foo import Foo will search one directory up, from ...foo import Foo will search two directories up, etc.

8. foo = __import__("foo")

Ever wondered how can you import a module dynamically? This is how. Obviously you wouldn’t use it with an explicit string, but rather with a variable of some kind. Also notice that you have to explicitly assign the imported module to a variable, or you won’t have access to its attributes.

9. reload(foo)

This statement does exactly what it looks like. It reloads the foo module. It’s pretty useful when you have a console open playing with a bit of code you’re tweaking and want to continue without resetting your interpreter.

Note: If you used from foo import bar, it’s not enough to reload foo for bar to update. You need to both reload foo and call from foo import bar again.

Import Loops

An import loop would occur in Python if you import two or more modules in a cycle. For example, if in foo.py you would from bar import Bar and in bar.py you from foo import Foo, you will get an import loop:

Traceback (most recent call last):
  File "foo.py", line 1, in <module>
    from bar import Bar
  File "/tmp/bar.py", line 1, in <module>
    from foo import Foo
  File "/tmp/foo.py", line 1, in <module>
    from bar import Bar
ImportError: cannot import name Bar

When this happens to you, the solution is usually to move the common objects from foo.py and bar.py to a different file (say common.py). However, sometime there’s actually a real loop of dependencies. For example, a method in Bar needs to create a Foo instance and vice versa. When the dependency is in a limited scope, you should remember that you can use the import command wherever you want. Putting imports at the top of the file is the common convention, but sometimes you can solve import loops by importing in a smaller scope, like in a method definition.

Easter Eggs

What fun would an easter egg be if you didn’t try it by yourself? Try these and have fun!

import antigravity
import this 
from __future__ import braces 
import __hello__ 
from __future__ import barry_as_FLUFL
Discuss this post at the comment section below.
Follow me on Twitter and Facebook

Similar Posts