How do I call a function from another .py file?
Categories:
Calling Functions Across Python Files: A Comprehensive Guide

Learn the essential techniques for organizing your Python code into multiple files and effectively calling functions defined in one file from another, enhancing modularity and reusability.
As Python projects grow in complexity, organizing your code into multiple files, known as modules, becomes crucial. This practice improves readability, maintainability, and reusability. A fundamental aspect of modular programming is the ability to call functions defined in one .py
file from another. This article will guide you through the primary methods for achieving this, from simple imports to more advanced considerations.
The Basics: Importing Modules
The import
statement is the cornerstone of modular programming in Python. It allows you to bring definitions (functions, classes, variables) from one module into another. When you import a module, Python executes its code once and makes its contents available to the importing script.
# my_module.py
def greet(name):
return f"Hello, {name}!"
def add(a, b):
return a + b
# main_script.py
import my_module
message = my_module.greet("Alice")
print(message)
result = my_module.add(5, 3)
print(result)
In the example above, main_script.py
imports my_module.py
. To call functions from my_module
, you prefix the function name with the module name (e.g., my_module.greet()
).
Alternative Import Forms
Python offers several ways to import modules and their contents, each with its own use case and implications for code readability and potential naming conflicts.
from module import *
might seem convenient, it's generally discouraged in production code. It pollutes the current namespace, making it harder to track where functions or variables originated and increasing the risk of naming collisions.# main_script_alt.py
from my_module import greet, add
# Now you can call greet and add directly without the 'my_module.' prefix
message = greet("Bob")
print(message)
result = add(10, 20)
print(result)
# Importing with an alias
import my_module as mm
message_alias = mm.greet("Charlie")
print(message_alias)
Using from module import function_name
allows you to directly access the function without the module prefix. Importing with an alias (import module as alias
) provides a shorter, more convenient name for the module, which is particularly useful for long module names or to avoid conflicts.
Understanding the Python Import Mechanism
When Python executes an import
statement, it follows a specific search path to locate the module. This path is defined by sys.path
, which includes the current directory, Python's installation directories, and any directories specified in the PYTHONPATH
environment variable. Understanding this mechanism is crucial for resolving ModuleNotFoundError
issues.
flowchart TD A[Start Import] B{Is module already loaded?} C[Return existing module] D[Search sys.path] E{Module found?} F[Execute module code] G[Add module to sys.modules] H[Return module object] I[Raise ModuleNotFoundError] A --> B B -- Yes --> C B -- No --> D D --> E E -- Yes --> F F --> G G --> H E -- No --> I
Python Module Import Process
ImportError
or unexpected behavior. Design your module dependencies carefully to avoid such scenarios.Organizing Larger Projects with Packages
For larger applications, simply placing .py
files in the same directory might not be sufficient. Python packages provide a way to structure modules into a directory hierarchy. A directory becomes a Python package if it contains an __init__.py
file (even if empty). This allows for more organized and complex module structures.
my_project/
├── main.py
└── utils/
├── __init__.py
└── string_ops.py
└── math_ops.py
# utils/string_ops.py
def capitalize_string(s):
return s.upper()
# utils/math_ops.py
def multiply(x, y):
return x * y
# main.py
from utils.string_ops import capitalize_string
from utils.math_ops import multiply
text = "hello world"
capitalized_text = capitalize_string(text)
print(capitalized_text)
product = multiply(7, 8)
print(product)
When working with packages, you use dot notation (package.module.function
) to specify the path to the function you want to import. This hierarchical structure makes it easier to manage dependencies and avoid naming conflicts across different parts of your application.