Previous | Tutorial index | Next
import StatementImport and use modules already in the Python programming/development environment.
In Tutorials 1 and 2, you learned what modules and packages are and how they are stored on your file system. But creating a module is only half the story. The real power comes when you import that module into another script or interactive session to use its functionality.
Think of importing like opening a toolbox: the tools (functions, classes, variables) are inside, but you can't use them until you open the box and take them out. In Python, the import statement is your key. It gives you access to thousands of built-in, standard library, and third-party tools. Mastering the various ways to import is essential for writing clean, efficient, and maintainable code.
import SyntaxThe simplest and most common way to use a module is with the basic import statement.
Syntax:
import module_name
What happens when you run this?
sys.path).Example:
import math
# Accessing content using dot notation
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
print(math.floor(3.7)) # 3
.) - Accessing the NamespaceThe dot (.) is the access operator. It tells Python: "Look inside the math namespace and find the attribute named sqrt."
This is the safest import method because it keeps the module's contents isolated in its own namespace. If you have a function called floor() in your own code, it won't conflict with math.floor() because they are in different namespaces.
dir() Function - Exploring Module ContentsYou can use dir() to see all the names (functions, classes, constants, and submodules) available inside a module.
import math
print(dir(math))
# Output: ['__doc__', '__loader__', '__name__', '__package__', ..., 'acos', 'acosh', 'asin', ..., 'pi', 'sqrt', ...]
This is incredibly useful for discovery and learning, especially when you are working with an unfamiliar module.
help() Function - Getting DocumentationYou can use help() to read the official documentation of a module or a specific function directly in your interactive session.
import math
help(math.sqrt)
# Output: Help on built-in function sqrt in module math:
# sqrt(x, /)
# Return the square root of x.
as KeywordSometimes, module names are long (e.g., matplotlib.pyplot), or you might want to use a standard abbreviation to make your code more concise. The as keyword allows you to assign a custom name (an alias) to the imported module.
Syntax:
import module_name as alias_name
Example:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Now you can use the aliases
array = np.array([1, 2, 3])
print(array)
When to use aliases:
pd for pandas, np for numpy). Using these makes your code recognizable to other Python developers.# Resolving a conflict between two potentially conflicting module names
import my_utilities as mu
import their_utilities as tu
mu.calculate() # Uses your function
tu.calculate() # Uses their function
When you type import something, Python follows a precise order to locate the module. Understanding this order is critical for troubleshooting ModuleNotFoundError.
Built-in Modules: Python first checks if the module is a built-in module (like sys, math, os). These are written in C and are hardcoded into the interpreter. This check happens very fast.
The Current Directory: Python then looks in the directory containing the script you are running (or the current working directory if you're in an interactive session). This is the first entry in sys.path.
PYTHONPATH Environment Variable: Python then checks the directories listed in the PYTHONPATH environment variable (if you have set one). This allows you to define custom global directories for your own libraries.
Standard Library Directories: Python then searches the default directories where the Python standard library is installed (e.g., /usr/lib/python3.10/ on Linux or C:\Python310\Lib on Windows).
Site-packages Directories: Finally, Python searches the site-packages directories, where all third-party modules and packages are installed via pip.
sys.pathYou can print sys.path to see the exact search order on your system:
import sys
for path in sys.path:
print(path)
Key Point: If you create a module with the same name as a built-in module (e.g., math.py) and save it in your current directory, Python will find your math.py first, because the current directory has higher priority than the built-in modules. This can lead to very confusing bugs. Best practice: Never name your files after built-in modules.
sys.path at RuntimeYou can programmatically add directories to sys.path to allow Python to find modules in non-standard locations.
import sys
sys.path.append("/path/to/my/custom/modules")
import my_module # Now this will work if my_module is in that folder
However, this is generally considered a hack and not recommended for production code. It's better to structure your project properly or set the PYTHONPATH environment variable.
__file__Most modules (except built-in ones) have a __file__ attribute that tells you the exact path of the .py file (or .pyc bytecode file) that Python loaded.
Example:
import math
print(math.__file__)
# Raises AttributeError: 'math' has no attribute '__file__' because it's a built-in C module.
import os
print(os.__file__)
# Output: /usr/lib/python3.10/os.py (or similar path)
This is very useful when:
When you use import module, the module's name becomes a variable in your current namespace. Be careful not to accidentally reassign it, as that will break your ability to access the module later.
Example of a mistake:
import math
math = 10 # Oops! Now 'math' is an integer. You can no longer do math.sqrt()!
print(math.sqrt(4)) # This will raise AttributeError: 'int' object has no attribute 'sqrt'
Best practice: Avoid using common module names as variable names in your scripts.
Test your knowledge before moving to the practical exercises.
Q1: Which keyword is used to give a module a shorter or alternative name during import?
A) as
B) alias
C) rename
D) with
Q2: In which order does Python search for a module?
A) Standard Library → Built-in → Current Directory → Site-packages
B) Current Directory → Built-in → Site-packages → Standard Library
C) Built-in → Current Directory → PYTHONPATH → Standard Library → Site-packages
D) PYTHONPATH → Current Directory → Built-in → Site-packages
Q3: What attribute of a module shows you the file location from which it was loaded?
A) __path__
B) __file__
C) __location__
D) __source__
Q4: True or False: If you have a script named random.py in your current directory, and you type import random, Python will always import the standard library random module.
Q5: What is the output of the following code?
import math
print(type(math))
A) <class 'module'>
B) <class 'function'>
C) <class 'math'>
D) <class 'file'>
These exercises will make you comfortable with importing, exploring, and working with modules in a live environment.
Goal: Import math and random, explore their contents, and use their functions.
Instructions:
import math and press Enter.dir(math) and look for the constants pi and e.help(math.degrees). Read what it does.math.sin() takes radians, so you need math.radians(90) or use math.pi/2).random module: import random.random.randint(1, 6) to simulate rolling a die 10 times.random.choice(['red', 'green', 'blue']) to randomly pick a color.Goal: Practice creating and using aliases.
Instructions:
datetime module with the alias dt.dt.datetime.now() to get the current date and time.json module with the alias js.data = {"name": "Alice", "age": 30}.js.dumps(data) to convert it to a JSON string.json module using its original name (json.dumps(data)). What error do you get? Why?sys.path and Module SearchGoal: Explore the search path and see what happens when you create a shadowing module.
Instructions:
Import sys and print sys.path to see all the directories Python searches.
Identify which directory is listed first (it should be an empty string '' or the current working directory).
Now, using your code editor, create a new file named random.py in your current directory with this content:
# random.py
print("This is my custom random module!")
def randint(a, b):
return 42 # Always returns 42
Save the file and close it.
In the Python interpreter (make sure it's running in the same directory), type import random.
Observe the print message "This is my custom random module!" – this proves Python loaded your file, not the built-in one.
Type random.randint(1, 100). What does it return? (It returns 42).
Delete the random.py file (or move it away) and restart the interpreter. Now import random will load the standard library module again.
dir() and help()Goal: Use dir() and help() to learn about an unfamiliar module.
Instructions:
os module.dir(os) to list everything inside it.listdir, rename, remove).help(os.listdir) to read about the listdir function.os.listdir('.') to list all files and folders in your current directory.| Problem | Likely Cause | Solution |
|---|---|---|
ModuleNotFoundError: No module named 'xyz' |
The module is not installed or Python cannot find it. | Check the spelling. If it's a third-party module, install it with pip install xyz. If it's your own module, ensure it's in the right directory or add its path to sys.path. |
ImportError: cannot import name 'xyz' |
You used from module import xyz, but xyz doesn't exist in that module. |
Check the spelling and case of the name. Use dir(module) to see the correct names. |
| Your import works in the terminal but fails in an IDE (like VS Code). | The IDE is running the script from a different working directory. | The current directory differs. Set the correct working directory in your IDE's run configuration, or use absolute paths in your project structure. |
AttributeError: module 'xyz' has no attribute 'func' |
You imported a module, but you are trying to access a name that doesn't exist there. | Check for typos. If you recently added the function to the module, restart the Python interpreter to clear the cache. |
| Module code seems to run twice. | You might be importing the module in multiple places, but more commonly, you have a script that is both run directly and imported elsewhere, causing its top-level code to execute. | Use the if __name__ == "__main__": guard to prevent top-level code from running on import. |
These questions are designed to test your practical ability and conceptual understanding.
Task: Create two modules in the same directory:
calculator.py: This module should contain four functions: add(a, b), subtract(a, b), multiply(a, b), divide(a, b) (with a check for division by zero).math_info.py: This module should contain a dictionary CONSTANTS with pi = 3.14159 and e = 2.71828, and a function describe() that prints "This module provides mathematical constants."Now, write a separate script called main.py in the same directory. In main.py:
calculator module with the alias calc.math_info module.calc to perform addition, subtraction, multiplication, and division on two numbers (e.g., 10 and 5), and print each result.pi from math_info.CONSTANTS.math_info.describe().Submission: Provide the full code for calculator.py, math_info.py, and main.py.
calculator.py:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return "Error: Division by zero!"
return a / b
math_info.py:
CONSTANTS = {
"pi": 3.14159,
"e": 2.71828
}
def describe():
print("This module provides mathematical constants.")
main.py:
import calculator as calc
import math_info
print("Calculator Results:")
print(f"10 + 5 = {calc.add(10, 5)}")
print(f"10 - 5 = {calc.subtract(10, 5)}")
print(f"10 * 5 = {calc.multiply(10, 5)}")
print(f"10 / 5 = {calc.divide(10, 5)}")
print()
print("Math Info:")
print(f"PI = {math_info.CONSTANTS['pi']}")
math_info.describe()
Task:
Write a Python script named search_path_demo.py that does the following:
sys.sys.path list, formatted so that each directory is on its own line.fantasy. Since this module doesn't exist, the script will raise a ModuleNotFoundError. Use a try-except block to catch this error and print a user-friendly message: "The module 'fantasy' could not be found. Please check your PYTHONPATH."try-except block, append a new, non-existent directory (e.g., /my_custom_libs) to sys.path.sys.path again to confirm the new directory was added.Submission: Provide your search_path_demo.py script and a brief explanation (2-3 sentences) of why the current working directory is often the most important entry in sys.path for beginners.
import sys
print("Current sys.path:")
for i, path in enumerate(sys.path):
print(f"{i}: {path}")
print("\nAttempting to import 'fantasy'...")
try:
import fantasy
except ModuleNotFoundError:
print("The module 'fantasy' could not be found. Please check your PYTHONPATH.")
# Append a new directory
sys.path.append("/my_custom_libs")
print("\nUpdated sys.path:")
for i, path in enumerate(sys.path):
print(f"{i}: {path}")
Explanation:
The current working directory (the first entry in sys.path) is crucial for beginners because when you save a Python script and run it from the terminal, the script's location automatically becomes the first place Python looks. This means any other .py files you create in the same folder can be imported without any extra configuration, making it very easy to organize code into multiple files.
Task:
You have a project folder containing a file named os.py. Inside this file, you wrote:
# os.py
def get_username():
return "Guest"
A colleague tries to run your project but complains that os.getcwd() doesn't work anymore.
Questions:
os.getcwd() fail when os.py exists in the project directory?os module and your custom get_username() function in the same script, without renaming your os.py file? (Hint: Use aliases).os.py (to call get_username()) and the standard library os (to call getcwd()). Explain what you had to do.1. Why os.getcwd() fails:
When os.py exists in the project directory, Python finds this file first (because the current directory is searched before the standard library). The standard library os module is never imported, so os.getcwd() doesn't exist.
2. How to fix without renaming: Use aliases to distinguish between the two modules:
import os as std_os # Standard library
import os as custom_os # Your custom os.py file
However, Python doesn't allow importing the same module name twice with different aliases in the same statement. You need to use different import strategies for each.
3. Working script:
# Use an alias for your custom module to avoid shadowing
import os as std_os
import os as custom_os
# Try importing your custom module separately after renaming the file, or use:
# Instead, rename your custom module to something unique like my_os.py
# Better approach: Rename your custom file to my_os.py
import my_os
import os as std_os
print(std_os.getcwd()) # Works: from standard library
print(my_os.get_username()) # Works: from your custom module
Alternatively, you can rename your custom os.py file to my_os.py and use:
import os
import my_os
print(os.getcwd())
print(my_os.get_username())
Task:
You are building a data conversion utility. Create a package named converter with the following structure:
converter/
├── __init__.py
├── length.py (functions: cm_to_inch, inch_to_cm)
└── temperature.py (functions: c_to_f, f_to_c)
Write the code for all functions (simple mathematical formulas).
In converter/__init__.py, import the four functions and assign them aliases so that users can call them directly from the package level, e.g.:
import converter
converter.cm_to_inch(10) # Works directly
converter.c_to_f(100) # Works directly
Write a test script test_converter.py that imports the package and converts:
Submission: Provide all files in a zip archive or paste the contents of each file in your answer.
converter/length.py:
def cm_to_inch(cm):
return cm / 2.54
def inch_to_cm(inch):
return inch * 2.54
converter/temperature.py:
def c_to_f(celsius):
return (celsius * 9/5) + 32
def f_to_c(fahrenheit):
return (fahrenheit - 32) * 5/9
converter/init.py:
from .length import cm_to_inch, inch_to_cm
from .temperature import c_to_f, f_to_c
test_converter.py:
import converter
cm_value = 5
print(f"{cm_value} cm = {converter.cm_to_inch(cm_value):.2f} inches")
celsius_value = 100
print(f"{celsius_value}°C = {converter.c_to_f(celsius_value):.1f}°F")
Task: In your own words (300-500 words), explain the concept of a "namespace" in Python as it relates to modules.
module.function()) considered safer than using wildcard imports (which we will discuss in Tutorial 4)?as keyword can be used to further manage namespaces effectively.Answer:
A namespace in Python is essentially a container that maps names to objects. When you import a module using import module, Python creates a namespace with the module's name and stores all the module's functions, classes, and variables inside it. This prevents naming conflicts between different modules by isolating their contents behind a prefix.
The dot notation module.function() is safer than wildcard imports (from module import *) because it maintains this separation. With dot notation, the origin of every function is immediately clear when reading the code. If two modules both define a calculate() function, module1.calculate() and module2.calculate() are unambiguous. With wildcard imports, the second import would overwrite the first, leading to silent bugs where the wrong function is called.
In a large team project, imagine two developers independently write helper modules: database.py and plotting.py. Both define a function named connect() (one connects to a database, the other connects points on a graph). Without dot notation, the team might not realize the conflict until the wrong connect() is called at runtime, causing subtle data corruption or misdisplayed graphs. With dot notation, the calling code explicitly states database.connect() and plotting.connect(), making the intended function obvious and preventing the bug entirely.
The as keyword provides additional namespace management by allowing developers to rename imports to avoid conflicts or improve readability. For example, import database as db creates a shorter, more convenient namespace. Similarly, from package import function as custom_function can differentiate between functions from different sources. This explicit control over naming makes code more maintainable and reduces the cognitive load on developers reading and debugging the code.
In summary, namespaces, dot notation, and aliases work together to create a clean, predictable, and safe environment for managing code dependencies.
import statement is the primary way to load modules into your program.module.function()) provides safe access to a module's contents by keeping them inside a dedicated namespace.as keyword allows you to create aliases, which improves conciseness and helps resolve naming conflicts.PYTHONPATH → Standard Library → Site-packages.sys.path and the location of a loaded module using module.__file__.dir() and help() functions are invaluable for exploring module contents and documentation interactively.This concludes the Tutorial 3. Once you have completed the exercises and homework, you will have a strong command of the import statement. You are now ready to move on to Tutorial 4, where we will dive into selective imports using from ... import ... and explore the nuances of importing specific parts from modules and packages!