Modules & ErrorsLesson 1 of 3
The Import System
Python's import system is simpler than JS modules in some ways and more structured in others. Every .py file is a module, and a directory of modules is a package. There is no node_modules folder: third-party packages are installed into a virtual environment (a .venv folder per project), and you declare dependencies in pyproject.toml (the modern standard) or a requirements.txt file.
The syntax maps cleanly. 'import { X } from "y"' becomes 'from y import X'. The as rename works the same way. There is no default export: you either import the module itself (import json) or names from it (from json import loads). The other big difference is Python's standard library: json, csv, re (regex), sqlite3, datetime, pathlib, http, and much more are built in. Many things that need npm install in JS need no installation at all.
Packages and __init__.py: a regular package is a directory containing an __init__.py file (often empty). The file runs when the package is first imported, so it can also re-export names, a bit like an index.js. Since Python 3.3, a directory without __init__.py can still be imported as a 'namespace package', but tools and test runners behave more predictably with regular packages, so include __init__.py in your own packages.
Modern type hints need fewer imports than older tutorials suggest. Since Python 3.9 you write list[str] and dict[str, int] with the built-in types, and since 3.10 you write str | None instead of Optional[str]. You will still see 'from typing import List, Optional' in older code; it works, but new code does not need it.
PEP 8 (Python's style guide) defines the import order: standard library first, then third-party packages, then your own local modules, with a blank line between each group. Tools like ruff and isort sort them for you automatically.
Quick reference
| JavaScript | Python | Note |
|---|---|---|
| import { join } from "path" | from os.path import join | Keyword order reversed |
| import * as fs from "fs" | import os | Import the whole module |
| import { x as y } | from m import x as y | Same rename idea |
| export default | No default exports | Import the module or its names |
| npm install / yarn add | pip install (inside a venv) | Package installer |
| package.json | pyproject.toml / requirements.txt | Dependency file |
| node_modules/ | .venv/ | Per-project environment |
| index.js in a folder | __init__.py | Runs when the package is imported |
Side by side
// JavaScript Modules
import { useState } from "react";
import React from "react";
import { useState as uState } from "react";
import * as path from "path";
const fs = require("fs");
// npm install / package.json / node_modules# Python Imports
# 1. Standard library
import json
import os
from collections import Counter
from pathlib import Path
# 2. Third-party (pip install requests numpy)
import numpy as np # rename
import requests
# 3. Local modules (your own files)
from myapp.utils import slugify
# Modern type hints: no typing import needed
def load(paths: list[str]) -> dict[str, int] | None:
...Exercise
Real Python, running in your browserOrganize these imports in PEP 8 order:
Ctrl + Enter runCtrl + Shift + Enter checkTab indentEsc then Tab to leave the editorCtrl + / comment