TypeError: __init__() missing 1 required positional argument

avatar

Borislav Hadzhiev

Last updated: Apr 20, 2022

banner

Photo from Unsplash

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.

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('Alice') print(emp1.name) # 👉️ "Alice"
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.

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(emp1.name) # 👉️ "" emp2 = Employee('Bob') print(emp2.name) # 👉️ "Bob"

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 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 = "Alice" def get_name(self): return self.name emp1 = Employee() print(emp1.name) # 👉️ "Alice"

We hardcoded the value for the name instance variable and set it to Alice.

Now every new instance is going to have a name attribute set to Alice.

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

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"

We created 2 instances, 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.

Conclusion #

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.

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.