Defining and Importing Python Modules

PythonPythonBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, you will learn about Python modules, which are files containing Python code that can be imported and used in other programs. This modular approach promotes code reuse and helps organize programs into logical components.

You will understand what Python modules are and why they are useful, learn how to create your own modules, practice using the import statement in different ways, and grasp the concept of a main module and when code executes. Prerequisites include a basic understanding of Python syntax and functions, and familiarity with creating and running Python scripts. It's recommended to restart your Python interpreter session before starting this exercise for a clean environment.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python(("Python")) -.-> python/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) python(("Python")) -.-> python/ErrorandExceptionHandlingGroup(["Error and Exception Handling"]) python(("Python")) -.-> python/FileHandlingGroup(["File Handling"]) python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python/ControlFlowGroup -.-> python/conditional_statements("Conditional Statements") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/ModulesandPackagesGroup -.-> python/importing_modules("Importing Modules") python/ModulesandPackagesGroup -.-> python/creating_modules("Creating Modules") python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("Classes and Objects") python/ErrorandExceptionHandlingGroup -.-> python/catching_exceptions("Catching Exceptions") python/FileHandlingGroup -.-> python/file_opening_closing("Opening and Closing Files") python/FileHandlingGroup -.-> python/file_operations("File Operations") subgraph Lab Skills python/conditional_statements -.-> lab-132395{{"Defining and Importing Python Modules"}} python/function_definition -.-> lab-132395{{"Defining and Importing Python Modules"}} python/importing_modules -.-> lab-132395{{"Defining and Importing Python Modules"}} python/creating_modules -.-> lab-132395{{"Defining and Importing Python Modules"}} python/classes_objects -.-> lab-132395{{"Defining and Importing Python Modules"}} python/catching_exceptions -.-> lab-132395{{"Defining and Importing Python Modules"}} python/file_opening_closing -.-> lab-132395{{"Defining and Importing Python Modules"}} python/file_operations -.-> lab-132395{{"Defining and Importing Python Modules"}} end

Understanding Python Modules

In Python, a module is like a container that holds Python definitions and statements. It's essentially a file, and the name of this file is the module name with the .py extension added at the end. Think of modules as toolboxes. They help you organize your Python code in a logical way, making it easier to reuse and maintain. Just like you'd keep different tools in separate boxes for better organization, you can group related Python code into different modules.

Let's take a look at the files that have been set up for this lab:

  1. First, we'll open the stock.py file in the editor to see what's inside. To do this, we'll use the following commands. The cd command changes the directory to the project folder where our file is located, and the cat command displays the contents of the file.
cd ~/project
cat stock.py

This stock.py file defines a Stock class. A class is like a blueprint for creating objects. In this case, the Stock class represents a stock. It has attributes (which are like characteristics) for the stock's name, the number of shares, and the price. It also has a method (which is like a function associated with the class) to calculate the cost of the stock.

  1. Next, let's examine the pcost.py file. We'll use the cat command again to view its contents.
cat pcost.py

This file defines a function called portfolio_cost(). A function is a block of code that performs a specific task. The portfolio_cost() function reads a portfolio file and calculates the total cost of all the stocks in that portfolio.

  1. Now, let's look at the sample portfolio data. We'll use the cat command to view the contents of the portfolio.dat file.
cat portfolio.dat

This file contains stock data in a simple format. Each line has the ticker symbol of the stock, the number of shares, and the price per share.

Using the import Statement

Python's import statement is a powerful tool that allows you to use code from other modules in your current program. It's like borrowing tools from other toolboxes. Let's practice using different ways to import code:

  1. First, we need to start the Python interpreter. The Python interpreter is a program that executes Python code. We'll use the following command to start it.
python3
  1. Now, let's import the pcost module and see what happens. When we use the import statement, Python looks for the pcost.py file and makes the code inside it available for us to use.
import pcost

You should see the output 44671.15. This is the calculated cost of the portfolio from the portfolio.dat file. When the pcost module is imported, the code at the bottom of the pcost.py file runs automatically.

  1. Let's try calling the portfolio_cost() function with a different portfolio file. We'll use the pcost.portfolio_cost() syntax to call the function from the pcost module.
pcost.portfolio_cost('portfolio2.dat')

The output should be 19908.75, which represents the total cost of the stocks in the second portfolio file.

  1. Now, let's import a specific class from the stock module. Instead of importing the whole module, we can just import the Stock class using the from...import statement.
from stock import Stock
  1. After importing the Stock class, we can create a Stock object. An object is an instance of a class. We'll create a Stock object with the name GOOG, 100 shares, and a price of 490.10. Then we'll print the name of the stock and calculate its cost using the cost() method.
s = Stock('GOOG', 100, 490.10)
print(s.name)
print(s.cost())

The output should be:

GOOG
49010.0
  1. Finally, when we're done using the Python interpreter, we can exit it using the exit() function.
exit()

This lab has demonstrated two different ways to import Python code:

  • import module_name - This imports the entire module, making all the functions, classes, and variables in that module available for use.
  • from module_name import specific_item - This imports only a specific item (like a class or a function) from the module, which can be useful if you only need a part of the module's functionality.

Understanding the Main Module in Python

In Python, when you run a script directly, it acts as the "main" module. Python has a special variable named __name__. When a file is executed directly, Python sets the value of __name__ to "__main__". This is different from when the file is imported as a module.

This feature is very useful because it allows you to write code that behaves differently depending on whether the file is run directly or imported. For example, you might want some code to run only when you execute the file as a script, but not when it's imported by another script.

Modifying pcost.py to Use the Main Module Pattern

Let's modify the pcost.py program to take advantage of this pattern.

  1. First, you need to open the pcost.py file in the editor. You can use the following commands to navigate to the project directory and create the file if it doesn't exist:
cd ~/project
touch pcost.py

The cd command changes the current directory to the project directory in your home directory. The touch command creates a new file named pcost.py if it doesn't already exist.

  1. Now, modify the pcost.py file to look like this:
## pcost.py

def portfolio_cost(filename):
    total_cost = 0.0

    with open(filename, 'r') as f:
        for line in f:
            fields = line.split()
            try:
                nshares = int(fields[1])
                price = float(fields[2])
                total_cost += nshares * price
            except (ValueError, IndexError):
                print(f"Couldn't parse: {line}")

    return total_cost

## This code only runs when the file is executed as a script
if __name__ == "__main__":
    total = portfolio_cost('portfolio.dat')
    print(total)

The main change here is that we've wrapped the code at the end in an if __name__ == "__main__": condition. This means that the code inside this block will only run when the file is executed directly as a script, not when it's imported as a module.

  1. After making these changes, save the file and exit the editor.

Testing the Modified Module

Now, let's test our modified module in two different ways to see how it behaves.

  1. First, run the program directly as a script using the following command:
python3 pcost.py

You should see the output 44671.15, just like before. This is because when you run the script directly, the __name__ variable is set to "__main__", so the code inside the if __name__ == "__main__": block gets executed.

  1. Next, start the Python interpreter again and import the module:
python3
import pcost

This time, you won't see any output. When you import the module, the __name__ variable is set to "pcost" (the module name), not "__main__". So, the code inside the if __name__ == "__main__": block doesn't run.

  1. To verify that the portfolio_cost function still works, you can call it like this:
pcost.portfolio_cost('portfolio.dat')

The function should return 44671.15, which means it's working correctly.

  1. Finally, exit the Python interpreter using the following command:
exit()

This pattern is very useful when creating Python files that can be used both as importable modules and as standalone scripts. The code inside the if __name__ == "__main__": block only runs when the file is executed directly, not when it's imported as a module.

โœจ Check Solution and Practice

Creating Your Own Module

Now that you understand how to use existing modules, it's time to create a new module from scratch. A module in Python is a file containing Python definitions and statements. It allows you to organize your code into reusable and manageable pieces. By creating your own module, you can group related functions and variables together, making your code more modular and easier to maintain.

Creating a Report Module

Let's create a simple module for generating stock reports. This module will have functions to read a portfolio file and print a formatted report of the stocks in the portfolio.

  1. First, we need to create a new file named report.py. To do this, we'll use the command line. Navigate to the project directory in your home directory and create the file using the touch command.
cd ~/project
touch report.py
  1. Now, open the report.py file in your preferred text editor and add the following code. This code defines two functions and a main block.
## report.py

def read_portfolio(filename):
    """
    Read a stock portfolio file into a list of dictionaries with
    keys: name, shares, price
    """
    portfolio = []
    with open(filename, 'r') as f:
        for line in f:
            fields = line.split()
            try:
                stock = {
                    'name': fields[0],
                    'shares': int(fields[1]),
                    'price': float(fields[2])
                }
                portfolio.append(stock)
            except (ValueError, IndexError):
                print(f"Couldn't parse: {line}")
    return portfolio

def print_report(portfolio):
    """
    Print a report showing the stock name, shares, price, and total value
    """
    print("Name    Shares    Price    Value")
    print("-" * 40)
    total_value = 0.0
    for stock in portfolio:
        value = stock['shares'] * stock['price']
        total_value += value
        print(f"{stock['name']:6s} {stock['shares']:9d} {stock['price']:9.2f} {value:9.2f}")
    print("-" * 40)
    print(f"Total Value: {total_value:16.2f}")

if __name__ == "__main__":
    portfolio = read_portfolio('portfolio.dat')
    print_report(portfolio)

The read_portfolio function reads a file containing stock information and returns a list of dictionaries, where each dictionary represents a stock with keys name, shares, and price. The print_report function takes a portfolio (a list of stock dictionaries) and prints a formatted report showing the stock name, number of shares, price, and total value. The main block at the end runs when the file is executed directly. It reads the portfolio file and prints the report.

  1. After adding the code, save and exit the editor.

Testing Your Module

Let's test our new module to make sure it works as expected.

  1. First, we'll run the script directly from the command line. This will execute the main block in the report.py file.
python3 report.py

You should see a formatted report showing the portfolio stocks and their values. This report includes the stock name, number of shares, price, and total value, as well as the total value of the entire portfolio.

Name    Shares    Price    Value
----------------------------------------
AA         100     32.20   3220.00
IBM         50     91.10   4555.00
CAT        150     83.44  12516.00
MSFT       200     51.23  10246.00
GE          95     40.37   3835.15
MSFT        50     65.10   3255.00
IBM        100     70.44   7044.00
----------------------------------------
Total Value:         44671.15
  1. Next, we'll use the module from the Python interpreter. Start the Python interpreter by running the python3 command in the terminal.
python3

Once the interpreter is running, we can import the report module and use its functions.

import report
portfolio = report.read_portfolio('portfolio.dat')
len(portfolio)  ## Should return 7, the number of stocks
portfolio[0]    ## First stock in the portfolio

The import report statement makes the functions and variables defined in the report.py file available in the current Python session. We then use the read_portfolio function to read the portfolio file and store the result in the portfolio variable. The len(portfolio) statement returns the number of stocks in the portfolio, and portfolio[0] returns the first stock in the portfolio.

You should see the following output:

7
{'name': 'AA', 'shares': 100, 'price': 32.2}
  1. Now, let's use the imported module to calculate the total cost of the portfolio ourselves. We'll iterate over the stocks in the portfolio and sum up the total value of each stock.
total = 0.0
for stock in portfolio:
    total += stock['shares'] * stock['price']
print(total)

The output should be 44671.15, which is the same as the total value printed by the print_report function.

  1. Finally, let's create a custom report for a specific stock type. We'll filter the portfolio to include only the IBM stocks and then use the print_report function to print a report for those stocks.
ibm_stocks = [stock for stock in portfolio if stock['name'] == 'IBM']
report.print_report(ibm_stocks)

This should print a report showing only the IBM stocks and their values.

Name    Shares    Price    Value
----------------------------------------
IBM         50     91.10   4555.00
IBM        100     70.44   7044.00
----------------------------------------
Total Value:         11599.00
  1. When you're done testing, exit the Python interpreter by running the exit() command.
exit()

You've now successfully created and used your own Python module, combining both functions and a main block that only runs when the file is executed directly. This modular approach to programming allows you to reuse code and make your projects more organized and maintainable.

โœจ Check Solution and Practice

Summary

In this lab, you have learned the fundamental concepts of Python modules and how to use them for code organization. Modules are Python files with reusable code, and the import statement enables you to utilize code from other modules in your program. The if __name__ == "__main__" pattern allows files to function as both importable modules and standalone scripts.

These concepts are crucial for writing maintainable Python code, especially when developing larger applications. As you continue learning Python, remember that modules help group related code, importing specific items keeps the namespace clean, and the main module pattern is a best practice. Applying these techniques will make your code more organized, maintainable, and reusable.