root@coding-prodigies:~# โ–Š
// lesson 2 of 11 ยท 15 min

Modules and packages

โš‘ Report an issue with this lesson

Any .py file is a module you can import from another file:

# utils.py
def slugify(text):
    return text.lower().replace(" ", "-")
# main.py
from utils import slugify

print(slugify("Hello World"))  # hello-world

The standard library has modules for almost everything before you reach for a third-party package:

import os
import json
import datetime

print(os.getcwd())
print(datetime.date.today())

A folder of related modules becomes a package once it contains an __init__.py file (in modern Python that file can even be empty โ€” its presence, or in newer versions just the folder structure itself, is what tells Python "treat this directory as importable"):

myapp/
    __init__.py
    utils.py
    models.py
from myapp import utils
from myapp.models import Course

There are two ways to reference another module: an absolute import spells out the full path from the project root (from myapp.models import Course), while a relative import uses dots to mean "relative to this module's own location" (from .models import Course, used from inside another file in the same package). Absolute imports are easier to read and are the more common choice in application code; relative imports show up mostly inside packages that need to refer to their own siblings without hardcoding the package's name.

You'll see this guard at the bottom of almost every runnable Python file:

def main():
    print("Running the program")

if __name__ == "__main__":
    main()

__name__ is a special variable every module gets automatically. When you run a file directly with python main.py, Python sets that file's __name__ to "__main__". But if that same file is instead imported from somewhere else, __name__ is set to the module's actual name instead. The if __name__ == "__main__": check means "only run this code when the file is executed directly, not when another file imports it" โ€” without it, importing a module for its functions would also re-run its entire script, side effects and all.

One gotcha worth knowing before it costs you twenty minutes of confusion: Python finds modules by searching the directories listed in sys.path, which normally starts with the directory containing the script you ran. If you name your own file json.py or random.py, it will shadow the real standard library module of the same name for every import in that project โ€” always avoid module names that collide with the standard library.

Try it yourself

Exercise: Write a slugify(text) function, like the one from utils.py in this lesson, that lowercases text and replaces spaces with hyphens. Then call it on 'Hello World' and print the result.
Expected output:
hello-world
python
Output

      
    

Run your code and get it working before marking this lesson complete.

// free preview

8 more lessons โ€” including Project: build a command-line notes tool โ€” plus a certificate are waiting.

Unlock the full course โ€” $59.99