Importing `*` in Python

This post discusses Python’s from <module> import * and from <package> import *, how they behave and why it may be (is!) a bad idea to use them.

 Importing * from a module

from <module> import * means “I want access to all the names in <module> that I’m meant to have access to”. So, let’s say we have the following something.py:

# something.py

public_variable = 42
_private_variable = 141

def public_function():
    print("I'm a public function! yay!")

def _private_function():
    print("Ain't nobody accessing me from another module...usually")

class PublicClass(object):
    pass

class _WeirdClass(object):
    pass

In the Python Interpreter, we can execute from something import * and see the following:

>>> from something import *
>>> public_variable
42
>>> _private_variable
...
NameError: name '_private_variable' is not defined
>>> public_function()
"I'm a public function! yay!"
>>> _private_function()
...
NameError: name '_private_function' is not defined
>>> c = PublicClass()
>>> c
<something.PublicClass object at ...>
>>> c = _WeirdClass()
...
NameError: name '_WeirdClass' is not defined

So, from something import * imports all the names from something other than the names that start with an _; because they are conventionally meant to be private.

 Ermm, that’s not too bad! Is that __all__?

What’s not mentioned above is what __all__ is. __all__ is a list of strings defining what symbols in a module (or a package as we’ll see later) will be exported when from <module> import * is used on the module. If we don’t define __all__ (we didn’t in something.py above), the default behaviour of import * is to import all names except those beginning with an underscore (_). Again, since conventionally an underscore is used to say a symbol is private, that all makes sense. Let’s see what happens when we define our own __all__ in something.py:

# something.py

__all__ = ['_private_variable', 'PublicClass']

# The rest is the same as before

public_variable = 42
_private_variable = 141

def public_function():
    print("I'm a public function! yay!")

def _private_function():
    print("Ain't nobody accessing me from another module...usually")

class PublicClass(object):
    pass

class _WeirdClass(object):
    pass

Now, we expect from something import * to only import the _private_variable and PublicClass names:

>>> from something import *
>>> public_variable
...
NameError: name 'public_variable' is not defined
>>> _private_variable
0
>>> public_function()
...
NameError: name 'public_function' is not defined
>>> _private_function()
...
NameError: name '_private_function' is not defined
>>> c = PublicClass()
>>> c
<something.PublicClass object at ...>
>>> c = _WeirdClass()
...
NameError: name '_WeirdClass' is not defined

 What about packages?

When importing * from a package, __all__ does approximately the same thing as for modules, except it deals with modules within the package (in contrast to specifying names within the module). So __all__ specifies all modules that shall be loaded and imported into the current namespace when we use from <package> import *.

However, the difference is, when you omit the declaration of __all__ in a package’s __init__.py, the statement from <package> import * will not import anything at all (not entirely true; Read this for the truth).

 But, why is this bad?

Before proceeding, in your Python Interpreter, import this and read The Zen of Python again (read it to your kids every night before they sleep too).

Explicit is better than implicit.

from <module> import * is not explicit. It isn’t telling us anything about what we’re importing or what names we’re bringing into our namespace. It would be much better to explicitly specify and import everything we need; that way, a reader (most likely your future self) won’t be confused about where a variable/function/class/etc. used in the code comes from, which leads us to:

Readability counts.

Even if a lot of names are required, it’s still much clearer to import them one by one explicitly. Use PEP 328:

from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, 
    LEFT, DISABLED, NORMAL, RIDGE, END)

You now know exactly what you have in your namespace and a quick ctrl+f can tell you where a name has come from.

Also, you are always at risk if/when the module/package author decides to change the contents of the list (add/remove stuff to/from it). Then, either:

  1. The author has removed a string from __all__. If your code was using that name, your code will raise a NameError and it’ll be harder to find out why.
  2. The author has added [many] new strings to __all__. You may not need all/any of the new names and you’re just bloating your namespace with stuff you don’t care about. They may even shadow some other names without you realising.

Of course, sometimes it may be useful or necessary to import * from modules and/or packages. However, it’s best to make sure you really have to before doing it. In my experience, this construct is usually used as a result of laziness more than anything else.


Discussion on hackernews and reddit.

 
396
Kudos
 
396
Kudos

Now read this

The Possibly Forgotten Optional `else` in Python’s `try` Statement

This post discusses the else clause in Python’s try statement. Although this particular use of else may not be as forgotten and controversial as its use in Python loops, a gentle reminder of how it works and when it’s useful may still be... Continue →