Functions, modules, and packages: a different kind of project shape
Translate from Node's file/module ecosystem into Python's function style, module imports, and package structure.
by the end of this lesson you can
- →Uses a normal Python function definition
- →Does not invent unnecessary module-level wrapper objects
- →Keeps import and call patterns simple
Overview
JavaScript and Node developers often think in terms of files, exports, package boundaries, and framework conventions. Python's modules and packages solve similar problems, but the structure and cultural defaults feel different.
In JavaScript/Node, you often
organize code around exported functions, object literals, and package-driven boundaries, with CommonJS or ESM shaping how modules connect.
In Python, the common pattern is
to lean on simple modules, explicit imports, and package directories without carrying over Node-specific export habits.
why this difference matters
A lot of early Python awkwardness comes from trying to make modules look and feel like JavaScript modules instead of letting Python's import model stay straightforward.
JavaScript/Node
export function greet(name) {
return `hello ${name}`;
}Python
def greet(name):
return f"hello {name}"Deeper comparison
JavaScript/Node version
import { readFile } from "node:fs/promises";
export async function loadConfig(path) {
const raw = await readFile(path, "utf8");
return JSON.parse(raw);
}Python version
import json
def load_config(path):
with open(path, "r", encoding="utf-8") as file:
return json.load(file)Reflect
What changes when you stop thinking in terms of exports and start thinking in terms of Python modules and package imports?
what a strong answer notices
A strong answer mentions simpler module surfaces, fewer explicit export lists, and an easier time reading what a file contributes to the package.
Rewrite
Rewrite this small Node module into a Python module and keep the public API obvious without JavaScript-style export ceremony.
Rewrite this JavaScript/Node
export const normalize = (value) => value.trim().toLowerCase();what good looks like
- Uses a normal Python function definition
- Does not invent unnecessary module-level wrapper objects
- Keeps import and call patterns simple
Practice
Sketch a small Python package layout for a CLI tool you would originally have written in Node. Explain where utilities, commands, and entry logic should live.
success criteria
- Uses modules and packages naturally
- Keeps responsibilities separated without JavaScript export patterns leaking through
- Explains how someone would import or run the code
Common mistakes
- Trying to reproduce export syntax or index-file patterns from Node in Python.
- Over-structuring a small Python package before the code needs it.
- Treating Python imports as if they behave like ESM path conventions.
takeaways
- ●A lot of early Python awkwardness comes from trying to make modules look and feel like JavaScript modules instead of letting Python's import model stay straightforward.
- ●A strong answer mentions simpler module surfaces, fewer explicit export lists, and an easier time reading what a file contributes to the package.
- ●Uses modules and packages naturally