1. python
  2. /advanced
  3. /modules

An Overview of Python Modules

What are Python Modules?

Think of Python modules as individual files containing functions, variables, classes, and other objects that we can use in our programs.

When we create files that hold our code, they can be executed either directly or imported into another Python program, where we can utilize the logic separately.

By separating our code into distinct modules, we'll find maintaining and reusing a whole lot easier.

Locating The Modules

When we import a module in Python, the interpreter doesn't just magically find it. Instead, it performs a search, looking for the module in several locations. First, it checks for built-in modules. If the module isn't found there, it turns to the sys.path variable within the sys module, which defines a list of directories to search. To have a better understanding of the process, we'll review it step by step.

Initially, the interpreter checks the current directory. If the module isn't present, it searches each directory listed in the PYTHONPATH environment variable. If it still hasn't found the module, it checks the installation-dependent list of directories, which are configured when Python is installed.

To have an overview of the directories that the interpreter searches for, you can try running the code below.

import sys
print(sys.path)

How to Import and Use Modules in Python

Now that we know where Python looks for modules, let's talk about how to import and use them in our programs. There are a few ways to import modules in Python, but the most common method is the trusty import statement.

import math

print(math.pi)

# Output: 3.141592653589793

We've imported the math module and used its pi constant. When we run the program, the value of pi is printed to the console. Additionally, we can import specific functions or variables from a module by turning to the from...import syntax.

from math import sqrt

print(sqrt(4))

Here, we've imported the sqrt function from the math module and used it to calculate the square root of 4.

Keep in mind that when we import a module, Python executes all of the code in that module. Well, this means that any functions or variables defined in the module will be available for use in your program.

We may be tempted to import all the names defined in a module using the from...import * syntax, but we should be cautious. The approach can lead to naming conflicts and make the code harder to understand. It's advisable to import only what we need.

Built-in Modules in Python

You might've noticed that we already used the built-in module in the previous section. Python comes packed with a variety of built-in modules that we can leverage. Let's explore some other commonly used built-in modules and see how they can enhance our Python programs.

The Random Module

The random module is apt for generating random numbers when we need to introduce some unpredictability.

import random

print(random.random()) # Generate a random float between 0 and 1

print(random.randint(1, 10)) # Generate a random integer between 1 and 10

print(random.choice(["Python", "JavaScript", "Java"])) # Randomly select an item from a list

The Datetime Module

Working with dates and times can be tricky, but often we can turn to the datetime module that contains classes designed for handling dates and times.

import datetime

now = datetime.datetime.now()

print(now) # Print the current date and time

print(now.year) # Print the current year

print(now.strftime("%Y-%m-%d")) # Print the date in the format YYYY-MM-DD

Learn more about Python Math

Understand the intricacies of Dates in Python

Exploring Module Contents

We might sometimes want to explore the available functions and objects within the selected module. That's where the dir() function comes in handy. As a built-in option, it returns a list of all the names defined in the current namespace or the names of an object passed as an argument. We can observe that by turning to the random module again and exploring its contents.

import random

print(dir(random))

Running this code will print a list of all the names defined in the module, giving us an overview of all the defined names at our disposal.

['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_ONE', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_accumulate', '_acos', '_bisect', '_ceil', '_cos', '_e', '_exp', '_floor', '_index', '_inst', '_isfinite', '_log', '_os', '_pi', '_random', '_repeat', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'choices', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randbytes', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']

Turning to Third-Party Modules

In addition to the built-in options, the Python ecosystem is brimming with thousands of third-party modules, ready to supercharge our programs. To get your hands on these modules, you'll need to use Python's package management system, pip.

To install a third-party module using pip, open a terminal or command prompt and type:

pip install module_name

Replace module_name with the name of the module you'd like to install. Once the module is installed, you can import it into your Python program like any other module.

Let's try out the requests module, a popular choice for making HTTP requests, and see it in action.

import requests

response = requests.get("https://jsonplaceholder.typicode.com/todos/1")
data = response.json()

print(f"Task title: {data['title']}")
print(f"Completed: {'Yes' if data['completed'] else 'No'}")

In this mock example, we're using the requests module to make an HTTP GET request to https://jsonplaceholder.typicode.com/todos/1, which returns a JSON object representing a to-do item. We then convert the response text to a Python dictionary using the json() method and print the task title and its completion status to the console.

Creating Custom Modules

Creating your own Python modules is a neat way to organize and reuse your code. To create a custom module, simply write your Python code in a separate file with a .py extension. To illustrate, we'll create a custom module that computes the factorial of a given number.

# my_module.py

def factorial(n):
    if n == 0 or n == 1:
        return 1
    return n * factorial(n - 1)

Our custom module contains a single function, factorial, which computes the factorial of a given number n using recursion.

To use this custom module in another Python program, import the module using the import statement:

import my_module

result = my_module.factorial(5)

print(f"Factorial of 5: {result}")

# Output: Factorial of 5: 120

Moreover, we should note that the module file's name (without the .py extension) is used as the module's name when importing it into another program.

Also, let's observe the difference between modules and packages in Python. While modules are single files containing Python code, packages are collections of related modules organized in a directory hierarchy. Packages provide a higher level of organization, allowing us to group related modules.

Final Thoughts

For a deeper understanding of Python modules, packages, and how they work together, we recommend exploring the official resources below, as well as some other core concepts.

Furthermore, don't hesitate to venture into the vast landscape of third-party options available on the Python Package Index, where you'll find solutions for virtually any task you can imagine.

Useful Resources

The Official Python Documentation on Modules

Index of all Python Modules

Numbers in Python

Variables in Python

Overview of Python Data Types