This guide answers one question: how to call a function that lives in another .py file—same directory, a package in another directory, or a module name you only know at runtime. It stays on practical import / from / importlib usage, not the full import system. For more call patterns, see Python call function examples. To structure multi-file projects as installable packages, see create a Python package; for functions that return several values to the caller, see return multiple values.
Tested on: Python 3.13.3; kernel 6.14.0-37-generic.
Multi-file layouts cannot run in a single in-browser snippet; examples use {run=false}. Create the files shown, cd to the project root shown in each section, then run python main.py (or python -m ... where noted).
Call a function from another file in the same folder
Put helpers.py and main.py in the same directory. The module name is the filename without .py.
helpers.py:
def add(a, b):
return a + bmain.py:
from helpers import add
print(add(2, 3))Run python main.py from that folder; it prints 5. Python adds the script’s directory to sys.path[0], so helpers resolves.
Import the whole file and call the function
Import the module once, then call attributes on it. This avoids cluttering your namespace and makes it obvious where each function comes from.
import helpers
print(helpers.add(2, 3))Import only one function from another file
Use from module import name when you only need specific callables (prefer named imports, not from module import *, which hides names and confuses static tools).
from helpers import add
print(add(10, 1))Call a function with arguments from another file
Calling looks the same as a normal function—arguments are passed at the call site in main.py; the imported function is defined with parameters in the other file.
helpers.py:
def greet(name, punctuation="!"):
return f"Hello, {name}{punctuation}"main.py:
from helpers import greet
print(greet("Ada"))
print(greet("Lin", punctuation="."))Call a function from another file in a different directory
Treat your code as a package: a directory that contains modules and is reachable on sys.path (usually the project root you run from).
Project structure
Example layout:
myapp/
__init__.py
utils/
__init__.py
mathops.py
main.pymyapp/utils/mathops.py:
def double(x):
return x * 2myapp/main.py:
from myapp.utils.mathops import double
print(double(21))From the parent of myapp (the directory that contains the myapp folder), run:
python -m myapp.mainUsing python -m sets package context so myapp is importable as a package.
Import using package.module syntax
The rule is: dotted path matches directories (packages) and the final segment is the module file (mathops.py → myapp.utils.mathops).
from myapp.utils import mathops
print(mathops.double(4))When do you need init.py?
In Python 3.3 and later, directories can be namespace packages without __init__.py in some layouts, but an empty __init__.py still marks a regular package clearly and matches most tutorials and tooling. If imports fail mysteriously, adding __init__.py files (even empty) in each package directory is a good first fix.
Call a function from a file inside a subfolder
If main.py sits next to a subfolder lib/ that holds your shared modules, add __init__.py in lib and import from the lib package:
project/
lib/
__init__.py
strings.py
main.pylib/strings.py:
def shout(s):
return s.upper()main.py:
from lib.strings import shout
print(shout("hi"))Run python main.py from project/.
Call a function from a parent directory
If your script sits in a nested folder but modules live above it, adjust sys.path once at startup (or restructure so -m from the project root is enough). Prefer fixing layout over long sys.path hacks in production.
project/tools/run.py:
import sys
from pathlib import Path
root = Path(__file__).resolve().parents[1]
if str(root) not in sys.path:
sys.path.insert(0, str(root))
from shared import identity
print(identity(99))project/shared.py:
def identity(x):
return xRun python tools/run.py from project/.
Dynamically call a function using importlib
importlib.import_module is the documented way to run the same import machinery using a string module name at runtime—it is still an import, not a way to skip the import system. After loading, use getattr on the module to fetch a function by name if needed.
import importlib
mod = importlib.import_module("helpers")
fn = getattr(mod, "add", None)
if callable(fn):
print(fn(2, 4))This assumes helpers.py is already importable on sys.path (same folder as the script you run, or installed as a package). For loading from an arbitrary file path without a package, see importlib.util.spec_from_file_location in the official docs.
Why ModuleNotFoundError happens
Typical causes:
- Running the script from the wrong working directory so the package root is not on
sys.path. - Filename vs import name:
helpers.pyimports ashelpers, notHelperson case-sensitive filesystems. - Missing
__init__.pyin a layout that your Python version or tool expects to be a regular package. - Running a file inside a package as a plain script (
python pkg/mod.py) so relative imports break; preferpython -m pkg.modfrom the parent ofpkg. - A name collision with a third-party module on
sys.path.
Common mistakes when importing functions from another file
- Using
from module import *, which pollutes globals and obscures names—import explicit symbols or the module. - Naming your script
email.py,json.py, or other stdlib names, which shadows real modules. - Editing
sys.pathin many places instead of one project root and consistent-mruns. - Expecting
importlib.import_moduleto avoid imports—it is the import system’s programmatic entry point. - Calling
import_modulewith a path string that is not a dotted package name (usespec_from_file_locationfor arbitrary paths).
Python import quick reference table
| Goal | Pattern |
|---|---|
| Same folder | from helpers import add (run from that folder) |
| Whole module | import helpers then helpers.add(...) |
| Package subpath | from pkg.sub import mod / from pkg.sub.mod import fn |
| Run as package | python -m pkg.entry from parent of pkg |
| Dynamic by name | importlib.import_module("pkg.mod") then getattr |
| Parent on path | sys.path.insert(0, str(Path(__file__).parents[1])) (temporary bridge) |
Summary
Call functions in other files by placing modules where Python can resolve them: same directory as the script you run, or a package tree imported with dotted names from the project root on sys.path. Prefer import module or from module import name over star-imports. For names known only at runtime, use importlib.import_module, which wraps the normal import mechanism. When ModuleNotFoundError appears, check working directory, package layout, __init__.py, and whether you should run with python -m.

