Skip to main content

Python Imports: How import Really Works (Modules, Packages, Paths)

Beginner20 min5 exercises55 XP
0/5 exercises

Think of a library. Instead of buying every book in the world and keeping them in your house, you go to the library and check out only the books you need. When you're done, you return them.

Python's import system works the same way. Python comes with hundreds of built-in modules — collections of useful code that other people have already written. Instead of writing everything from scratch, you import just the tools you need.

In this tutorial, you'll learn the different ways to import code in Python, how to rename imports for convenience, what __name__ == '__main__' means, and how Python finds the modules you ask for.

What Is the Difference Between import and from...import?

There are two main ways to bring code into your program. The first is import, which brings in an entire module. The second is from...import, which grabs just the specific pieces you want.

Let's start with the basic import statement. When you write import math, Python loads the entire math module. To use anything from it, you prefix it with the module name.

Using import with the module name
Loading editor...

Notice you always write math.sqrt(), not just sqrt(). The module name acts like a label that keeps things organized. It's like saying "the sqrt function from the math module."

Now compare that to from...import. This pulls specific names directly into your code, so you can use them without the module prefix.

Using from...import
Loading editor...

With from math import sqrt, pi, you get sqrt and pi directly — no prefix needed. But you don't get floor or anything else you didn't import. And math itself isn't available as a name.

import math
import math

math.sqrt(16)    # Must use prefix
math.pi          # Must use prefix
# Everything in math is available
from math import sqrt, pi
from math import sqrt, pi

sqrt(16)    # No prefix needed
pi          # No prefix needed
# Only sqrt and pi are available

How Do You Import Specific Names from a Module?

You can import one name, several names, or (in rare cases) everything from a module. Let's look at each option.

Importing one or many names
Loading editor...

You might see code that uses from module import *. This imports everything from the module at once. It seems convenient, but it's almost always a bad idea.

Why import * is dangerous
Loading editor...

How Do You Rename Imports with as?

Sometimes module names are long or you want a shorter nickname. The as keyword lets you create an alias — a shorter name for the module or function.

Module alias with as
Loading editor...

After import math as m, you use m.sqrt() instead of math.sqrt(). The original name math is no longer available — only the alias m works.

You can also alias individual imports from from...import.

Aliasing specific imports
Loading editor...

What Does __name__ == '__main__' Mean?

Every Python file has a special variable called __name__. When you run a file directly, Python sets __name__ to the string '__main__'. When you import that file from somewhere else, __name__ gets set to the module's name instead.

Checking __name__
Loading editor...

This is useful because it lets you write code that behaves differently depending on whether it's being run directly or imported as a module.

The if __name__ guard
Loading editor...

Think of it like this: the if __name__ == '__main__' block is the front door of your program. If someone runs your file directly, they come through the front door and see the demo. If another file imports your code, they go through the side door and only get the functions — no demo runs.

How Does Python Find the Modules You Import?

When you write import math, Python doesn't magically know where math lives. It searches through a list of directories in a specific order. This list is stored in sys.path.

Viewing sys.path
Loading editor...

Python checks these locations in order:

  • The current directory (where your script lives)
  • Directories in PYTHONPATH (an environment variable you can set)
  • The standard library (built-in modules like math, os, json)
  • Installed packages (third-party libraries you've installed)
  • If Python searches every location and can't find the module, you get a ModuleNotFoundError.

    What happens when a module is not found
    Loading editor...

    You can also check where a module is located after importing it using the __file__ attribute (when available).

    Inspecting modules
    Loading editor...

    How Do Real Python Programs Use Imports?

    In real Python projects, imports always go at the top of the file. There's a standard ordering convention that keeps things tidy.

    Conventional import ordering
    Loading editor...

    Practice Exercises

    Predict the Output: import vs from...import
    Predict Output

    What will this code print?

    from math import sqrt, pow
    
    a = sqrt(49)
    b = pow(2, 3)
    print(a)
    print(b)

    Remember that math.pow() returns a float.

    Loading editor...
    Use the random Module
    Write Code

    Import the random module and use random.seed(42) to make results predictable. Then:

    1. Use random.randint(1, 100) to generate a random number and print it

    2. Create a list colors = ['red', 'blue', 'green', 'yellow']

    3. Use random.choice(colors) to pick a random color and print it

    The seed ensures the same "random" numbers every time.

    Loading editor...
    Fix the Bug: Broken Imports
    Fix the Bug

    This code has import errors. Fix all the problems so it runs correctly and produces the expected output.

    Expected output:

    4.0
    3.141592653589793
    5
    Loading editor...
    Use Import Aliases
    Write Code

    Import the datetime module with the alias dt. Then:

    1. Create a date object for January 15, 2025 using dt.date(2025, 1, 15) and store it in my_date

    2. Print the date using print(my_date)

    3. Print the year using print(my_date.year)

    4. Print the weekday name using print(my_date.strftime('%A'))

    Loading editor...
    Write a Module with __name__ Guard
    Write Code

    Write a small "module" that:

    1. Defines a function celsius_to_fahrenheit(c) that returns c * 9/5 + 32

    2. Defines a function fahrenheit_to_celsius(f) that returns (f - 32) * 5/9

    3. Has an if __name__ == '__main__' guard that:

    - Prints 'Running temperature converter'

    - Prints celsius_to_fahrenheit(0)

    - Prints celsius_to_fahrenheit(100)

    - Prints fahrenheit_to_celsius(212)

    Loading editor...