TypeError: __init__() missing 1 required positional argument

avatar
Borislav Hadzhiev

Last updated: Apr 8, 2024
7 min

banner

# Table of Contents

  1. TypeError: __init__() missing 1 required positional argument
  2. TypeError: missing 2 required positional arguments

# TypeError: __init__() missing 1 required positional argument

The Python "TypeError: __init__() missing 1 required positional argument" occurs when we forget to provide a required argument when instantiating a class.

To solve the error, specify the argument when instantiating the class or set a default value for the argument.

typeerror init missing 1 required positional argument

Here is an example of how the error occurs.

main.py
class Employee(): # 👇️ takes `name` arg def __init__(self, name): self.name = name def get_name(self): return self.name # ⛔️ TypeError: Employee.__init__() missing 1 required positional argument: 'name' emp1 = Employee()

We tried instantiating the Employee class but didn't provide a value for the name argument which caused the error.

# Provide a value for the argument to solve the error

One way to solve the error is to provide a value for the argument.

main.py
class Employee(): def __init__(self, name): self.name = name def get_name(self): return self.name # 👇️ Make sure to pass the argument emp1 = Employee('Bobby Hadz') print(emp1.name) # 👉️ "Bobby Hadz"

provide value for argument

When we instantiate a class, we should provide all the arguments that we have specified in the class's __init__() method (other than self which is passed automatically).

When a class defines the __init__() method, the method is invoked when an instance is created.

If your class doesn't define an __init__() method, you don't have to pass any arguments when instantiating it.

If you pass arguments when instantiating a class, the arguments are passed on to the __init__() method.

# Using a default value for the argument to solve the error

An alternative solution is to set a default value for the argument.

main.py
class Employee(): # 👇️ Set default value for `name` arg def __init__(self, name=''): self.name = name def get_name(self): return self.name emp1 = Employee() print(repr(emp1.name)) # 👉️ "" emp2 = Employee('Bobby Hadz') print(emp2.name) # 👉️ "Bobby Hadz"

use default value for argument to solve error

We set an empty string as the default value for the name argument.

Now, we aren't required to provide a value for the argument when instantiating the class.

Note that the first argument the __init__() method takes is self.

You could name this argument anything because the name self has no special meaning in Python.

self represents an instance of the class, so when we assign a variable as self.my_var = 'some value', we are declaring an instance variable - a variable unique to each instance.

If you get the error "TypeError: missing 1 required positional argument: 'self'", check out the following article.

# Using a hardcoded initial value to solve the error

If you are just hard coding an initial value for the argument in the __init__() method, you can remove it and hardcode the value in the method.

main.py
class Employee(): # 👇️ removed arg def __init__(self): # 👇️ hardcoded value self.name = "Bobby Hadz" def get_name(self): return self.name emp1 = Employee() print(emp1.name) # 👉️ "Bobby Hadz"

use hardcoded initial value to solve error

We hardcoded the value for the name instance variable and set it to "Bobby Hadz".

Now every new instance is going to have a name attribute set to "Bobby Hadz".

You can update the value for the attribute later on in your code, e.g. emp1.name = 'Alice'.

# Avoid setting default values for non-primitive arguments

An important note is to avoid setting default values for non-primitive arguments, e.g. dictionaries and lists.

Here is an example of how this can go wrong.

main.py
class Employee(): # 👇️ default arg of type dict def __init__(self, address={}): self.address = address emp1 = Employee() emp2 = Employee() emp1.address['country'] = 'Germany' print(emp1.address['country']) # 👉️ "Germany" print(emp2.address['country']) # 👉️ "Germany"

avoid setting default values for non primitive arguments

We created 2 instances and updated the address in 1, but the change is reflected in both instances.

This is because default arguments are only evaluated once - when the function is defined.

They are not evaluated each time the function is called.

When a non-primitive default argument like a dictionary or list is mutated, it is mutated for all function calls.

One way to get around this issue is to set the default argument to None and conditionally update its value in the body of the function.

main.py
class Employee(): def __init__(self, address=None): self.address = address if address is None: self.address = {} emp1 = Employee() emp2 = Employee() emp1.address['country'] = 'Germany' print(emp1.address['country']) # 👉️ "Germany" print(emp2.address['country']) # ⛔️ KeyError: 'country'

The body of the method is run every time it is invoked, so the issue no longer exists.

# Solve the error when working with 2 classes

The error also occurs when forgetting to pass arguments to a second class when instantiating it.

main.py
class Person(): def __init__(self, name): self.name = name class Employee(Person): def __init__(self, name, salary): self.name = name self.salary = salary # ⛔️ TypeError: Person.__init__() missing 1 required positional argument: 'name' Person.__init__(self) def get_name(self): return self.name emp1 = Employee('Bobby', 50) print(emp1)

We instantiated the Person class in the __init__ method of the Employee class but forgot to pass a value for the name argument.

To solve the error, provide a value for the name argument when instantiating the class.

main.py
class Person(): def __init__(self, name): self.name = name class Employee(Person): # 👇️ removed arg def __init__(self, name, salary): self.name = name self.salary = salary # ✅ passing a value for `name` Person.__init__(self, name) def get_name(self): return self.name emp1 = Employee('Bobby', 50) print(emp1.name) # 👉️ Bobby print(emp1.salary) # 👉️ 50

provide default value for name argument

We passed a value for the name argument to solve the error.

You can also use the super() method to instantiate the parent class.

main.py
class Person(): def __init__(self, name): self.name = name class Employee(Person): def __init__(self, name, salary): self.name = name self.salary = salary # ✅ using super() super().__init__(name) def get_name(self): return self.name emp1 = Employee('Bobby', 50) print(emp1.name) # 👉️ Bobby print(emp1.salary) # 👉️ 50

Notice that we didn't pass the self argument when using super().

The super() method gives us access to the base class without explicitly referring to it.

We could replace the call to super() with Employee to achieve the same result.

However, we would have to pass self as the first argument to the __init__ method when using Employee.

The super() method is more flexible and more commonly used than explicitly referring to the base class.

The call to the parent's __init__ method runs the method and assigns the attributes of the parent to the instance.

Now you can access the attributes of the parent class on an instance of the child class.

Want to learn more about using the self keyword in Python? Check out these resources: Purpose of 'return self' from a class method in Python,TypeError: missing 1 required positional argument: 'self'.

# TypeError: missing 2 required positional arguments (Python)

The Python "TypeError: missing 2 required positional arguments" occurs when we forget to provide 2 required arguments when calling a function or method.

To solve the error, specify the arguments when calling the function or set default values for the arguments.

typeerror missing 2 required positional arguments

Here is an example of how the error occurs.

main.py
# 👇️ takes 2 arguments - `a` and `b` def do_math(a, b): return a + b # ⛔️ TypeError: do_math() missing 2 required positional arguments: 'a' and 'b' result = do_math()

The do_math function takes 2 positional arguments - a and b, but we called the function without providing values for the arguments.

# Provide a value for the arguments in the call to the function

One way to solve the error is to provide a value for the arguments.

main.py
def do_math(a, b): return a + b result = do_math(10, 10) print(result) # 👉️ 20

We passed values for the arguments to the function which solves the error.

If we define a function that takes 2 arguments, we have to provide values for the arguments when the function is called.

# Set default values for the function's parameters

An alternative solution is to set default values for the function's parameters.

main.py
def do_math(a=0, b=0): return a + b result = do_math() print(result) # 👉️ 0

We set 0 as the default value for the 2 arguments. This could be any other value, e.g. an empty string ("") or even None if you can't think of a suitable default value.

If the function gets invoked without providing values for the a and b arguments, the default values are used.

# Hardcoding values for the arguments

If you are simply hard coding values for these arguments, you can remove the arguments and declare variables in the body of the function.

main.py
def do_math(): a = 100 b = 200 return a + b result = do_math() print(result) # 👉️ 300

We hardcoded the values for a and b.

# Don't use non-primitive values for default parameters

An important note is to avoid setting default values for non-primitive arguments, e.g. dictionaries and lists.

Here is an example of how this can go wrong.

main.py
def get_address(address={}): return address addr1 = get_address() addr2 = get_address() addr1['country'] = 'Germany' print(addr1) # 👉️ {'country': 'Germany'} print(addr2) # 👉️ {'country': 'Germany'}

We called the get_address() function 2 times and stored the results in variables.

Notice that we only set the country key on one of the dictionaries, but both of them got updated.

This is because default arguments are only evaluated once - when the function is defined.

They are not evaluated each time the function is called.

When a non-primitive default argument like a dictionary or list is mutated, it is mutated for all function calls.

One way to get around this issue is to set the default argument to None and conditionally update its value in the body of the function.

main.py
def get_address(address=None): if address is None: address = {} return address addr1 = get_address() addr2 = get_address() addr1['country'] = 'Germany' print(addr1) # 👉️ {'country': 'Germany'} print(addr2) # 👉️ {}

The body of the function is run every time it is invoked, so the issue no longer exists.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.