Join us and get access to thousands of tutorials and a community of expert Pythonistas.
This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.
Introducing __all__
00:00
It took some preamble, but we’re finally here. It’s time to talk about __all__. __all__ is a list you can define to control what gets exported from your packages and modules.
00:10
It’s used by wildcard imports. Each item in __all__ should be a string corresponding to the name of an importable object. And in that way, you could say __all__ defines the module’s public API.
00:23 One important thing to note is that explicit imports will not be affected by
00:31
__all__. Another thing to consider is that __all__ behaves differently when it’s in a module or a package. As a reminder, modules are individual .py files, while packages are the directories that contain modules and sometimes sub-packages, and generally also have a __init__ file.
00:46
So in a package’s __init__.py, without __all__, a wildcard import will bring nothing into the file’s namespace. With __all__, only listed names are imported from the package.
00:59
Whereas in a module, without __all__, all public names are imported, like you just saw. But with __all__, only the names included in the list will be imported. To get hands-on, we’ll start by looking at how this works for packages.
01:14
First, let’s set up a package to play with. You can grab the shapes package from the course resources. I’ve got it open in an IDE. shapes is a directory holding four files.
01:25
A __init__ that is empty, a circle module defining a Circle class, a square module defining a Square class, fittingly, and a utils module defining a validate() function that is used by both the circle and square modules. The details of the code is incidental, but that’s the general structure of the package.
01:43
Now open up a REPL, and remember, __init__ is currently empty. Try a wildcard import from the shapes package. from shapes import *, and call dir() to see what was brought in.
01:56
And nothing at all. This is because the __init__ file does not define __all__. Now try adding a __all__ to the __init__ file. __all__ equals the list with the strings "circle" and "square".
02:10
Importantly, circle and square match the file names of the modules exactly, not including the .py ending. Now you can reload the REPL and try your import again.
02:26
call dir(), and now you can see both circle and square have been imported. If you examine them, circle,
02:34
square, you’ll see that they both represent their respective modules. From here, you can access their contents via dot notation, just like you saw before.
02:43
circle.Circle returns the class Circle. I’m sure you can already think of some great uses for __all__, but there’s still more to see.
Become a Member to join the conversation.