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

Importing "*" From a Package

In this lesson, you’ll learn about importing * from a package. For the purposes of the following discussion, the previously defined package is expanded to contain some additional modules:

Illustration of hierarchical file structure of Python packages

There are now four modules defined in the pkg directory. Their contents are as shown below.

mod1.py:

Python
def load_data():
    print('loading data using mod1.load_data()')

class Customer:
    pass

mod2.py:

Python
def clean_data():
    print('cleaning data using mod2.clean_data()')

class Location:
    pass

Locked learning resources

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

Unlock This Lesson

Already a member? Sign-In

Locked learning resources

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

Unlock This Lesson

Already a member? Sign-In

00:00 In this video, you’ll learn more about importing using the asterisk (*) from a package. To delve in a little deeper about using that wildcard, you’re going to need to expand the current package a bit.

00:11 So, here’s the pkg/ directory. Right now, your package contains mod1 and mod2, but I’m going to have you add additional modules mod3 and mod4 to help illustrate the wildcard importing. Let me have you take a look.

00:26 Inside that pkg/ folder, go ahead and delete the file __init__.py,

00:33 and then create the two other mod files, mod3.py and mod4.py.

00:49 Make sure that they’re within the pkg/ directory. Okay, so mod1 has a function named load_data() that prints out 'loading data', and a class called Customer.

01:01 mod2 has a clean_data() function that prints out 'cleaning data', and it has a class called Location. mod3—inside of mod3 define a new function called merge_data(). For this example, make a print() statement, 'merging data using merge_data()'.

01:24 It doesn’t need to be an f-string.

01:28 And for a class, create a class called Message. And save. mod4—you’re going to have another function called send_mail(),

01:48 and a class called Winner. Okay, so mod3, make sure you’ve saved. mod4, make sure you saved. mod2 and mod1great. Okay. Back here, go ahead and restart your REPL session.

02:04 You may remember the dir() function that shows the local symbol table.

02:10 Again, it returns the names and the current scope. So right now, here are all the names that are available. If you were to use from pkg.mod3, for example, and import everything using import *, what did that add?

02:25 Well, that added the two objects—the class Message and the function merge_data(). So again, merge_data() is available. If you were to type Message, you can see that it’s coming from pkg.mod3the class Message. Go ahead and exit and restart the REPL one more time. Take a look at dir().

02:50 What if you went from pkg and tried to import everything using import *? What’s going to happen? Well, it doesn’t import anything.

03:00 There’s a convention that import * uses inside of Python, where it looks for something called an __all__ list, or the dunder __all__ attribute.

03:11 Let me have you create one.

03:16 A little bit ago, I had you delete the __init__.py file, but now I’d like you to recreate that file. And inside of it, add a list and its name will be __all__. So again, it would look like this, re-adding the __init__.py file.

03:32 Now let me show you the rest of it in the code. Exit the REPL, and here inside of pkg/, make a new file creating a __init__ file again.

03:43 And in that __init__ file, you’re going to create a single variable, a single object that will be __all__, and it’s going to be a list.

03:55 __all__ =, and here I’ll have you create this list of the modules. In fact, they need to be text strings, and you don’t need the '.py' at the end.

04:11 Okay. So here you go. The __all__ list for __init__.py is going to include 'mod1', 'mod2', 'mod3', and 'mod4' in the square brackets of a list, and save.

04:20 So that’s the only thing that’s in __init__.py.

04:24 Now back here, make sure that you’ve saved. The current directory shows this. Now if you use from pkg import the wildcard, asterisk (*), what did that do? That actually imported all of the modules.

04:41 So now mod1.load_data() is available. Even mod4—that class mod4.Winner is available.

04:53 This form of wild import using the star (*)–is it considered a good development practice? Whether for packages or modules, it is a feature that gives the creator of the package the control over what happens when import * is specified, meaning that if you have an __all__ list inside your __init__.py file, you can determine what happens when a user of your package does this command.

05:21 And similarly, you can actually do that same thing for modules. You can actually specify an __all__ list inside of a module in case there are certain things that you don’t want to be imported when using a wildcard. What does that look like? Open up mod1

05:39 exiting the REPL again—and inside mod1 at the top, specify a __all__ list and inside of it include just 'load_data'.

05:51 So now, if you were to go back into the REPL—again, make sure that you’ve saved mod1, having this new __all__ list inside of it.

06:02 Type dir() to see the current scope, the local symbol table, and then try out using pkg.mod1, importing via the wildcard, asterisk (*).

06:13 What did that do? That put 'load_data' into the local symbol table. load_data(), that function, can be called and used. Well, what about Customer? Customer isn’t defined, it did not get imported even though it’s part of the package mod1. Using this __all__ method allowed you to specify as a wildcard what gets imported. And more importantly, with a module, it can be what doesn’t get imported, which is pretty cool.

06:40 Let me review that with you. The __all__ list controls what is imported when import * is specified. For a package, when the __all__ list is not defined, using import * doesn’t import anything.

06:56 But for a module, when the __all__ is not defined, import * imports everything—and this is a review—except names that are starting with an underscore (_).

07:06 Hence, why you may want to define one. In the next video, I’ll show you about subpackages.

Avatar image for Jakob Fredriksson

Jakob Fredriksson on July 28, 2020

I’ve been grinding Python for a couple of months by now but I’ve been cheating and “skipped” some basics. Basics like this. Great teaching throughout this course, much desired and much needed basics fell in place.

Your color-theme btw? It’s awesome!

Become a Member to join the conversation.