Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

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:23 from shapes import *,

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.

02:50 In the next lesson, we’ll dig even deeper.

Become a Member to join the conversation.