How to call another Python file in Python

Learn how to call another Python file in Python. Explore different methods, tips, real-world applications, and common error debugging.

How to call another Python file in Python
Published on: 
Mon
Apr 6, 2026
Updated on: 
Wed
Apr 8, 2026
The Replit Team

To call another Python file is an essential skill for modular code. This practice helps you organize code into reusable modules, which makes projects cleaner and more efficient to manage.

In this article, you'll learn several techniques to call files, complete with practical tips, real-world applications, and common debugging advice to help you master this fundamental skill.

Using import statement

import helper
result = helper.calculate(10, 5)
print(f"Result from helper module: {result}")--OUTPUT--Result from helper module: 15

The import statement is the most common way to call another file in Python. It treats the target file—in this case, helper.py—as a module. This gives you access to all the functions and variables defined within it.

You can then call a specific function using dot notation, such as helper.calculate(). This approach is great for keeping your code organized because it namespaces everything from the imported file, preventing potential naming conflicts with your main script.

Basic import techniques

Beyond the standard import, you can fine-tune your workflow using from ... import for specific functions, import as for aliases, and importlib.reload() for dynamic updates.

Using from ... import to import specific functions

from helper import calculate, multiply
result1 = calculate(10, 5)
result2 = multiply(10, 5)
print(f"Addition: {result1}, Multiplication: {result2}")--OUTPUT--Addition: 15, Multiplication: 50

The from ... import statement allows you to pull specific functions or variables directly into your script's namespace. This makes your code more concise because you can call functions like calculate() directly, without the helper. prefix.

  • Direct access: You can use imported functions such as calculate and multiply as if they were defined in your current file.
  • Naming conflicts: This approach can create naming conflicts if your main script already has functions with the same names, so use it thoughtfully.

Using module aliases with import as

import helper as h
import datetime as dt

result = h.calculate(10, 5)
current_time = dt.datetime.now()
print(f"Result: {result}, Time: {current_time.strftime('%H:%M:%S')}")--OUTPUT--Result: 15, Time: 14:30:25

The import as statement lets you assign a custom alias to a module. It's especially handy for modules with long names or when you want a shorter prefix. In the example, helper is aliased as h, and the standard datetime library is shortened to dt, making your code more concise.

  • Improved readability: Aliases like dt for datetime are a common convention that makes code quicker to read and write.
  • Convenience: You can call functions using the shorter alias, like h.calculate(), which simplifies your code without cluttering the global namespace.

Reloading modules with importlib.reload()

import helper
import importlib

# After modifying helper.py, reload it
importlib.reload(helper)
result = helper.calculate(10, 5)
print(f"Result after reload: {result}")--OUTPUT--Result after reload: 15

The importlib.reload() function is essential for dynamic development, especially when you're testing changes on the fly. Python caches imported modules, meaning it only loads them once. If you modify a module like helper.py after it's already been imported, reload() forces Python to re-execute the module's code and apply your updates without restarting the entire script.

  • Live updates: This is incredibly useful in interactive sessions or long-running applications where you need to see changes immediately.

Advanced module techniques

While standard imports cover most cases, Python also provides dynamic methods like __import__(), subprocess, and runpy.run_module() for more complex scenarios and greater control.

Using __import__() for dynamic imports

module_name = "helper"
helper_module = __import__(module_name)
result = helper_module.calculate(10, 5)
print(f"Dynamically imported result: {result}")--OUTPUT--Dynamically imported result: 15

The __import__() function is Python's mechanism for dynamic imports, letting you load a module using its name as a string. This is powerful when you don't know which module you'll need until your program is running—for example, loading different modules based on user input or a configuration file.

  • Runtime Flexibility: Unlike a standard import, __import__() takes a variable like module_name and returns the corresponding module object.
  • Under the Hood: It's the function that powers the import statement itself, but you'd use it directly for more complex scenarios.

Running Python files with subprocess

import subprocess

result = subprocess.run(["python", "helper.py"], capture_output=True, text=True)
print("Output from helper.py:")
print(result.stdout)--OUTPUT--Output from helper.py:
Helper module executed directly!

The subprocess module lets you run another Python file as a completely separate process, much like you would from your terminal. This approach is fundamentally different from import because it doesn't load the file as a module; it executes it independently.

  • Isolated execution: The script runs in its own environment, which is perfect for standalone applications or tasks you want to keep separate.
  • Output capturing: By setting capture_output=True, you can grab any output the script prints, which is then accessible via the stdout attribute.

Executing modules with runpy.run_module()

import runpy

namespace = runpy.run_module("helper", run_name="__main__")
print(f"Module executed with name: {namespace['__name__']}")
print(f"Available functions: {[f for f in namespace if callable(namespace[f]) and not f.startswith('__')]}")--OUTPUT--Module executed with name: __main__
Available functions: ['calculate', 'multiply']

The runpy.run_module() function executes a module's code and returns its global variables in a dictionary. Setting run_name="__main__" is the key—it makes the module behave as if you ran it directly from the terminal. This is perfect for triggering code inside an if __name__ == "__main__": block.

  • Simulates direct execution: It allows you to run a file like helper.py as a top-level script from within another script.
  • Inspectable namespace: The returned dictionary gives you full access to the module's functions and variables after it has run.

Move faster with Replit

Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. This lets you move from learning individual techniques to building complete applications with Agent 4. Instead of piecing together modules manually, you can describe the app you want to build and let the Agent handle the code, databases, APIs, and deployment.

  • A unit conversion tool that dynamically loads calculation modules for length, weight, or currency using __import__().
  • A data pipeline that uses subprocess to run a separate validation script before processing a file.
  • A dashboard that imports functions from multiple helper files to display real-time analytics.

Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.

Common errors and challenges

Importing modules is powerful, but you might encounter errors like ModuleNotFoundError; here’s how to navigate these common challenges.

Resolving ModuleNotFoundError when importing custom modules

A ModuleNotFoundError is one of the most frequent issues you'll face. It simply means Python cannot locate the file you're trying to import. This usually happens if the module isn't in the same directory as your main script or isn't in a folder included in Python's search path.

  • Check your directory structure: The easiest fix is to ensure both your main script and the module you're calling (e.g., helper.py) are in the same folder.
  • Use packages for larger projects: If your project is spread across multiple folders, turn them into packages by adding an empty __init__.py file in each directory. This allows you to use relative imports, like from . import helper, to reliably call files within your project structure.

Handling circular import dependencies

Circular imports occur when two or more modules depend on each other. For example, if moduleA.py imports moduleB.py, but moduleB.py also imports moduleA.py, Python gets stuck in a loop and will likely raise an ImportError because neither module can be fully loaded first.

The best way to fix this is to refactor your code. Identify the functions or classes that both modules need and move them into a third, neutral module, such as utils.py. This breaks the dependency cycle, as both modules can import from utils.py without importing each other.

Troubleshooting AttributeError after importing a module

An AttributeError appears when you try to access a variable or function that doesn't exist on the imported module. For instance, you might see AttributeError: module 'helper' has no attribute 'calculat'. This is often caused by a simple typo in the function name.

Another common cause is confusion between import styles. If you use import helper, you must call the function with the prefix, like helper.calculate(). If you use from helper import calculate, you call it directly as calculate(). Forgetting the prefix or using it unnecessarily will trigger this error. When in doubt, you can use dir(helper) to get a list of all available attributes in the module.

Resolving ModuleNotFoundError when importing custom modules

When working with your own custom modules, you'll likely run into a ModuleNotFoundError. This error pops up when Python can't locate your file. See what happens when you try to import a module that isn't in a recognized path.

import my_custom_module

result = my_custom_module.process_data([1, 2, 3])
print(f"Processed result: {result}")

This import fails because Python has no path to my_custom_module. Since it isn't a built-in library or in a known folder, a ModuleNotFoundError is raised. The following code shows how to fix this.

import sys
sys.path.append('/path/to/module_directory')
import my_custom_module

result = my_custom_module.process_data([1, 2, 3])
print(f"Processed result: {result}")

To fix this, you can dynamically modify Python's search path. The sys.path list is where Python looks for modules. By using sys.path.append() with the directory containing your file, you’re giving Python a direct route to find my_custom_module. This method is a powerful way to manage imports in projects with non-standard folder layouts, ensuring your custom code is always accessible when you need it.

Handling circular import dependencies

A circular import creates a deadlock where two files are waiting on each other to load, causing your program to fail. This happens when one module imports a second, but the second module also imports the first. The code below shows this problem.

# This approach causes circular import errors
import dependent_module

def calculate_value(x):
return dependent_module.transform(x) * 2

Here, the script imports dependent_module, which also imports the current script. This mutual dependency creates a loading deadlock. The code below shows how to restructure your files to break this cycle and resolve the error.

def calculate_value(x):
# Import inside the function to avoid circular imports
import dependent_module
return dependent_module.transform(x) * 2

A quick fix is to delay the import by moving it inside the function that uses it. Placing import dependent_module inside calculate_value() postpones the import until the function is called, which breaks the initial loading deadlock. This local import technique is a practical solution when a full code refactor is too complex. Keep an eye out for this issue in large projects where modules often reference each other, as it can be tricky to spot.

Troubleshooting AttributeError after importing a module

An AttributeError is a common roadblock, often caused by a simple typo when calling a function. Python raises this error when it can't find the exact attribute you've requested. See this mistake in action with the following code.

import math

# Incorrect function name
result = math.squareroot(25)
print(f"Square root: {result}")

The code attempts to call squareroot, but the math module doesn't have a function with that name, triggering the error. The following code demonstrates how to resolve this by using the correct function name.

import math

# Correct function name is sqrt, not squareroot
result = math.sqrt(25)
print(f"Square root: {result}")

The fix is straightforward: use the correct function name. The math module's function is sqrt, not squareroot. This error is a frequent slip-up, often just a typo. When you encounter an AttributeError, double-check the spelling of the function or attribute you're calling. You can also use dir() on the module to list all its available attributes and confirm the correct name.

Real-world applications

Mastering import techniques and their pitfalls lets you build sophisticated applications, like configuration managers and dynamic plugin systems.

Using imports for configuration management

You can use conditional imports to manage your application's settings, making it simple to switch between different configurations for environments like development and production.

# Choose environment
env = "development" # Could be "production" in a real scenario

if env == "development":
from config.dev import settings
else:
from config.prod import settings

print(f"Database URL: {settings.DATABASE_URL}")
print(f"Debug mode: {settings.DEBUG}")

This code uses a conditional from ... import statement to load different settings based on the env variable. It’s a practical way to manage configurations without cluttering your main script with environment-specific logic. By changing the env string, you can easily switch between different setups.

  • The development configuration might use a local database and enable detailed error messages.
  • The production setup would connect to the live database and disable debugging for better performance and security.

This keeps your application flexible and your sensitive credentials separate.

Creating a plugin system with dynamic __import__()

You can use the __import__() function to build a flexible plugin system that loads modules dynamically using their names as strings.

def load_plugin(plugin_name):
try:
plugin = __import__(f"plugins.{plugin_name}", fromlist=["execute"])
return plugin.execute
except ImportError:
print(f"Plugin '{plugin_name}' not found")
return None

selected_plugin = "image_processor"
plugin_func = load_plugin(selected_plugin)
if plugin_func:
result = plugin_func("sample.jpg")
print(f"Plugin result: {result}")

This code uses the __import__() function to dynamically load a module based on a string variable. It constructs the full module path, like plugins.image_processor, at runtime. This allows you to call different modules without hardcoding their names, making the code highly adaptable.

  • The fromlist argument is crucial; it tells Python to return the specific submodule (image_processor) instead of the top-level plugins package.
  • The function then extracts and returns the execute function from the loaded module, which can be called later in the script.

Get started with Replit

Now, turn these techniques into a real tool. Describe what you want to build to Replit Agent, like “a unit converter that loads different calculation modules” or “a dashboard that imports functions from multiple helper files.”

The Agent will write the code, test for errors, and deploy your application for you. Start building with Replit.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.

Get started free

Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.