Python Imports: How import Really Works (Modules, Packages, Paths)
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.
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.
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
math.sqrt(16) # Must use prefix
math.pi # Must use prefix
# Everything in math is availablefrom math import sqrt, pi
sqrt(16) # No prefix needed
pi # No prefix needed
# Only sqrt and pi are availableHow 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.
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.
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.
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.
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.
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.
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.
Python checks these locations in order:
math, os, json)If Python searches every location and can't find the module, you get a ModuleNotFoundError.
You can also check where a module is located after importing it using the __file__ attribute (when available).
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.
Practice Exercises
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.
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.
This code has import errors. Fix all the problems so it runs correctly and produces the expected output.
Expected output:
4.0
3.141592653589793
5Import 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'))
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)