backend / python core / 07_python_imports.md

Types of Imports in Python

3 interview angles 2 min read source

Types of Imports in Python

1. Standard Library Imports

  • Purpose: To use modules that are part of Python’s standard library.
  • Example:
    import math
    import os

2. Third-Party Module Imports

  • Purpose: To use modules or libraries installed using package managers like pip.
  • Example:
    import numpy
    import pandas as pd

3. User-Defined Module Imports

  • Purpose: To reuse code from user-defined modules or scripts.
  • Example:
    import my_module
    from my_module import my_function

4. Absolute Imports

  • Purpose: To import modules using the full path from the project’s root.
  • Example:
    from package.subpackage.module import function

5. Relative Imports

  • Purpose: To import modules relative to the current module’s location (often used within packages).
  • Example:
    from . import module  # Current package
    from ..subpackage import another_module  # Parent package

6. Wildcard Imports

  • Purpose: To import all public symbols from a module (not recommended due to namespace pollution).
  • Example:
    from math import *

7. Selective Imports

  • Purpose: To import specific functions, classes, or variables from a module.
  • Example:
    from math import sqrt, pi

8. Aliased Imports

  • Purpose: To provide a shorter or more meaningful name for the module.
  • Example:
    import numpy as np
    import pandas as pd

9. Dynamic Imports

  • Purpose: To import a module dynamically at runtime.
  • Example:
    module_name = "math"
    math_module = __import__(module_name)
    print(math_module.sqrt(16))

10. Lazy Imports (Python 3.7+ with importlib)

  • Purpose: To import a module only when it’s first used, improving startup time.
  • Example:
    import importlib
    math = importlib.import_module('math')
    print(math.sqrt(16))

Best Practices

  • Use explicit imports (from module import item) over wildcard imports for clarity.
  • Avoid circular imports by structuring your code well.
  • Use __all__ in modules to control what gets imported with a wildcard import.

import math
import os

# Third-Party Module Imports
import numpy
import pandas as pd

# User-Defined Module Imports
import my_module
from my_module import my_function

# Absolute Imports
from package.subpackage.module import function

# Relative Imports
from . import module  # Current package
from ..subpackage import another_module  # Parent package

# Wildcard Imports (not recommended)
from math import *

# Selective Imports
from math import sqrt, pi

# Aliased Imports
import numpy as np
import pandas as pd

# Dynamic Imports
module_name = "math"
math_module = __import__(module_name)
print(math_module.sqrt(16))

# Lazy Imports (Python 3.7+)
import importlib
math = importlib.import_module('math')
print(math.sqrt(16))

Interview angle

  • “What happens on import x?” - Python checks sys.modules first, then searches sys.path, executes the module top to bottom once, and caches it. Repeated imports return the cached module, which is why module-level code runs exactly once.
  • “How do you fix a circular import?” - usually by moving the shared piece to a third module, or importing inside the function where it’s needed. A circular import is normally a signal that the module boundary is wrong.
  • “Absolute or relative imports?” - absolute for clarity and refactor-safety; relative within a package is acceptable and common. Mixing them inconsistently is what makes packages fragile.