When working with imported modules in Python (like math, json, csv, or your own custom modules), you might encounter errors such as TypeError: 'module' object is not callable or TypeError: 'module' object is not subscriptable. These errors indicate a fundamental misunderstanding of how to access the contents (functions, classes, variables) within an imported module.
This guide explains why modules themselves cannot be called like functions or indexed like lists/dictionaries, and provides the correct ways to access their members.
Understanding Python Modules
A Python module is essentially a file containing Python definitions and statements (like functions, classes, and variables). When you use import my_module, Python executes the code in my_module.py (if it hasn't already) and creates a module object. This module object acts as a namespace – a container holding all the names (functions, classes, variables) defined within that file.
Crucially, the module object itself is not a function you can call directly with (), nor is it a sequence or mapping you can access with square brackets []. You need to access the specific items inside the module namespace.
Error 1: 'module' object is not callable
This error occurs when you treat the imported module object as if it were a function or a class constructor by putting parentheses () after its name.
Cause: Calling the Module Directly (module(...))
Error Scenario 1: Built-in module
import math
try:
result = math(3.14) # What function did you intend to call?
except TypeError as e:
print(e)Error Scenario 2: Custom module
def add(a, b):
return a + bimport another
try:
sum_result = another(5, 10)
except TypeError as e:
print(f"\nCustom module error: {e}")You cannot "call" the container (the module); you must call a specific function or class within it.
Solution 1: Access and Call Functions/Classes within the Module (module.function())
Use dot notation (.) to access the desired function or class inside the module, and then call it with parentheses ().
def add(a, b):
return a + bimport math
import another
result_floor = math.floor(3.14) # Access 'floor' via dot, then call
print(f"math.floor(3.14) = {result_floor}") # Output: 3
result_add = another.add(5, 10) # Access 'add' via dot, then call
print(f"another.add(5, 10) = {result_add}") # Output: 15Solution 2: Import Specific Functions/Classes Directly (from module import function)
Import the specific function or class name directly into your current namespace. This allows you to call it without the module prefix.
def add(a, b):
return a + bfrom math import floor, ceil
from another import add
result_floor = floor(3.14) # No 'math.' prefix needed
result_ceil = ceil(3.14) # No 'math.' prefix needed
result_add = add(5, 10) # No 'another.' prefix needed
print(f"floor(3.14) = {result_floor}") # Output: floor(3.14) = 3
print(f"ceil(3.14) = {result_ceil}") # Output: ceil(3.14) = 4
print(f"add(5, 10) = {result_add}") # Output: add(5, 10) = 15This is often preferred for commonly used functions as it makes the code less verbose.
Error 2: 'module' object is not subscriptable
This error occurs when you use square brackets [...] with the imported module object, as if trying to access an item by index (like a list) or by key (like a dictionary).
Cause: Using Square Brackets on the Module (module[...])
settings = {'host': 'localhost', 'port': 8080}import config
try:
host_value = config['host']
except TypeError as e:
print(e)Modules themselves don't support indexing or key lookup via [].
Solution 1: Access Variables/Collections within the Module First (module.variable[...])
Use dot notation to access the specific variable (which might be a list, dictionary, etc.) inside the module, and then use square brackets on that variable.
settings = {'host': 'localhost', 'port': 8080}import config
settings_dict = config.settings
print(f"Settings dict: {settings_dict}")
host_value = settings_dict['host']
port_value = config.settings['port'] # Combine in one step
print(f"Host: {host_value}") # Output: Host: localhost
print(f"Port: {port_value}") # Output: Port: 8080Solution 2: Import Specific Variables Directly (from module import variable)
Import the specific variable (list, dictionary, etc.) directly into your current namespace.
settings = {'host': 'localhost', 'port': 8080}from config import settings
host_value = settings['host']
port_value = settings['port']
print(f"Host: {host_value}") # Output: Host: localhost
print(f"Port: {port_value}") # Output: Port: 8080Debugging with dir()
If you're unsure what names (attributes, functions, classes, variables) are available within an imported module, use the dir() function.
settings = {'host': 'localhost', 'port': 8080}import math
print("--- dir(math) ---")
print(dir(math))
print("\n--- dir(config) ---")
print(dir(config))Conclusion
TypeError exceptions involving 'module' object typically stem from treating the module itself as something it's not:
'module' object is not callable: You tried to call the module like a function (module()). Solution: Call a specific function/class within the module using dot notation (module.function()) or import the function/class directly (from module import function, thenfunction()).'module' object is not subscriptable: You tried to use square brackets on the module (module[...]). Solution: Access the desired variable (list, dict, etc.) within the module using dot notation first, then use square brackets on that variable (module.variable['key']ormodule.variable[index]), or import the variable directly (from module import variable, thenvariable[...]).
Remember that import module_name gives you access to the module namespace, and you need to use dot notation or specific imports (from ... import ...) to access the items contained within that namespace.