TypeError: __init__() missing required positional argument in Python OOP
Pass all required arguments to the class constructor or define default values and type annotations in __init__.
Root Cause Analysis
This error occurs when Python tries to instantiate a class object, but the arguments provided in the constructor call do not satisfy the required positional parameters defined in init.
1. Class Instantiation Protocol
When you call a class like User('alice'), Python's object creation protocol first calls __new__() to allocate memory for the instance, and then immediately calls __init__(self, ...) to initialize instance attributes. The first parameter self is passed automatically by Python. Any additional parameters defined without default values in __init__ are mandatory positional arguments.
2. Missing Parameters vs Extra Parameters
If caller code omits one or more mandatory arguments, Python raises TypeError: __init__() missing N required positional argument(s). Conversely, passing too many arguments triggers TypeError: __init__() takes N positional arguments but M were given. Both errors stem from signature mismatches at instantiation time.
3. Subclassing and super().init() Pitfalls
In class hierarchies, if a subclass overrides __init__ but forgets to forward required arguments to super().__init__(), the parent class constructor will fail with this exact TypeError.
4. Resolving Constructor Mismatches
To prevent this error, provide all required constructor arguments at instantiation, specify sensible default values in the signature, or leverage modern @dataclass decorators with type hints.
Reproduction Code (MCVE)
class UserAccount:
def __init__(self, username: str, email: str):
self.username = username
self.email = email
# TypeError: __init__() missing 1 required positional argument: 'email'
user = UserAccount('alice')
Solution 1: Provide All Required Arguments at Instantiation
Provide all mandatory arguments specified by the class constructor signature, using keyword arguments for improved code clarity.
class UserAccount:
def __init__(self, username: str, email: str):
self.username = username
self.email = email
# Correct: Pass both required parameters
user = UserAccount(username='alice', email='alice@example.com')
print(f'User created: {user.username} ({user.email})')
Solution 2: Define Default Values or Use @dataclass
Define optional fallback values in the __init__ signature or use @dataclass from the standard library for clean and maintainable data containers.
from dataclasses import dataclass
from typing import Optional
@dataclass
class UserAccount:
username: str
email: Optional[str] = None
is_active: bool = True
# Instantiation succeeds with defaults
user = UserAccount(username='alice')
print(f'User: {user.username}, active={user.is_active}, email={user.email}')
A frequent beginner mistake is forgetting the self parameter in method definitions (e.g., def __init__(username):), which causes Python to pass the instance as username and complain that mandatory arguments are missing. Contrast this TypeError with AttributeError: 'UserAccount' object has no attribute 'email', which occurs when __init__ completes but fails to assign an attribute to self. When using mutable default arguments like items: list = [], always default to None and initialize self.items = items or [] inside __init__ to avoid shared state across instances.