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.
* 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 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
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 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
# 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
>>> 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:
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:
- The author has removed a string from
__all__. If your code was using that name, your code will raise a
NameErrorand it’ll be harder to find out why.
- 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.