Import Modules and Packages in Python

PythonBeginner
Practice Now

Introduction

In this lab, you will learn the fundamentals of organizing and reusing code in Python by working with modules and packages. We will start by understanding what a Python module is and how its execution behavior changes depending on whether it's run directly or imported.

You will then practice the two primary ways to bring code from modules into your program: the import statement for loading an entire module and the from...import statement for loading specific functions or variables. Finally, you will learn how to structure related modules into a package to create a well-organized and scalable project. All coding will be done within the WebIDE, using Python files and the terminal.

This is a Guided Lab, which provides step-by-step instructions to help you learn and practice. Follow the instructions carefully to complete each step and gain hands-on experience. Historical data shows that this is a beginner level lab with a 94% completion rate. It has received a 97% positive review rate from learners.

Understanding Python Modules

A module in Python is simply a file containing Python code, which has a .py extension. Modules allow you to logically organize your code, making it easier to manage and reuse. Functions, classes, and variables defined in a module can be used in other scripts.

In your WebIDE, you will see a file explorer on the left side. The lab environment has already created a file named hello.py in the ~/project directory.

First, open hello.py to examine its contents. It should contain the following code:

print("This code runs on import or direct execution.")

if __name__ == "__main__":
    print("This code runs ONLY when the script is executed directly.")

The if __name__ == "__main__": block is a special construct in Python. The __name__ variable is a built-in variable that evaluates to the name of the current module. When a Python script is run directly from the command line, its __name__ is set to the string "__main__". This if statement allows you to write code that will only execute when the file is run as the main program, not when it is imported by another module.

Let's see this in action. Open the terminal in your WebIDE and run the hello.py script directly:

python3 hello.py

You will see the following output, as both print statements are executed:

This code runs on import or direct execution.
This code runs ONLY when the script is executed directly.

This demonstrates the behavior of a script when it is the main program being executed. In the next step, we will see what happens when we import it as a module.

Importing Modules with the import Statement

The most common way to use a module is to import it using the import statement. This makes all the code in the module available to your current script.

In the file explorer, you will find an empty file named main.py. This will be our main script for the rest of the lab.

Open main.py and add the following line to import the hello module:

import hello

print("The main.py script has finished.")

Save the file. Now, run main.py from the terminal:

python3 main.py

Observe the output carefully:

This code runs on import or direct execution.
The main.py script has finished.

Notice that only the first print statement from hello.py was executed. The code inside the if __name__ == "__main__": block was skipped. This is because when main.py imports hello, the __name__ variable within the hello.py context is set to "hello" (the module's name), not "__main__". This feature is essential for creating reusable modules that don't produce unwanted side effects upon import.

Now, let's work with a module that contains more than just print statements. Open the module_a.py file. It contains a variable, a function, and a class.

PI = 3.14159

def greet(name):
 print(f"Hello, {name} from module_a!")

class Calculator:
    def add(self, x, y):
        return x + y

Modify main.py to import module_a and use its members. To access a member of an imported module, you use the syntax module_name.member_name.

Replace the content of main.py with the following:

import module_a

## Access the PI variable
print(f"The value of PI is {module_a.PI}")

## Call the greet function
module_a.greet("LabEx")

## Create an instance of the Calculator class and use its method
calc = module_a.Calculator()
result = calc.add(5, 3)
print(f"5 + 3 = {result}")

Save the file and run it:

python3 main.py

The output will be:

The value of PI is 3.14159
Hello, LabEx from module_a!
5 + 3 = 8

This demonstrates how the import statement loads an entire module, and you access its contents using the module's name as a prefix.

Importing Specific Objects with from...import

Sometimes, you only need a few specific items from a module. The from...import statement allows you to import specific functions, classes, or variables directly into your current script's namespace. This means you can use them without the module_name. prefix.

Let's modify main.py to use this import method. Instead of importing the entire module_a, we will import only the PI variable and the greet function.

Update main.py with the following code:

from module_a import PI, greet

## Access PI and greet directly without the module prefix
print(f"The value of PI is {PI}")
greet("World")

Save the file and run it from the terminal:

python3 main.py

The output will be:

The value of PI is 3.14159
Hello, World from module_a!

As you can see, PI and greet are used directly. However, if you try to access something you didn't import, like the Calculator class, you will get an error.

Try it now. Add the following lines to the end of main.py:

calc = Calculator()
print(calc.add(10, 20))

Run the script again:

python3 main.py

This time, the script will fail with a NameError:

The value of PI is 3.14159
Hello, World from module_a!
Traceback (most recent call last):
  File "/home/labex/project/main.py", line 7, in <module>
    calc = Calculator()
NameError: name 'Calculator' is not defined

This error confirms that only the objects specified in the from...import statement are brought into the current namespace. This method can make your code more readable but also increases the risk of naming conflicts if you import objects with the same name from different modules.

Before moving to the next step, remove the two lines that caused the error from main.py.

Understanding and Using Python Packages

As projects grow, you may want to organize related modules into a single directory hierarchy. This is what packages are for. A package is a directory that contains a special file named __init__.py (which can be empty). The presence of this file tells Python to treat the directory as a package.

Let's create a package to hold our module_a.

First, create a new directory named my_package in the ~/project directory. You can do this by right-clicking in the file explorer and selecting "New Folder".

mkdir my_package

Next, create the required __init__.py file inside the new my_package directory.

touch my_package/__init__.py

Now, move module_a.py into the my_package directory. You can drag and drop the file in the file explorer.

mv module_a.py my_package/

Your project structure should now look like this:

~/project/
├── main.py
├── hello.py
└── my_package/
    ├── __init__.py
    └── module_a.py

With this package structure in place, we need to update how we import module_a in our main.py script. To import a module from a package, you use dotted module names, like package_name.module_name.

Open main.py and modify it to import the greet function from my_package.module_a:

from my_package.module_a import greet

greet("Package")

Save the file and run it:

python3 main.py

You should see the following output:

Hello, Package from module_a!

This shows how to import a specific object from a module inside a package. Alternatively, you could import the module itself:

## Alternative import style
import my_package.module_a

my_package.module_a.greet("Alternative")

Packages are a powerful tool for organizing large codebases, such as libraries and frameworks, into a clear and maintainable structure.

Summary

In this lab, you have learned the essential concepts of code organization in Python. You started by understanding what a module is and the purpose of the if __name__ == "__main__": block for creating reusable code. You then practiced importing modules using the import module_name syntax and accessing their members with dot notation.

Furthermore, you explored the from...import statement to bring specific objects from a module directly into your script's namespace. Finally, you learned how to structure related modules into a package by creating a directory with an __init__.py file, and how to import from that package. These skills are fundamental for writing clean, organized, and scalable Python applications.