Borislav Hadzhiev
Wed Apr 20 2022·3 min read
Photo by Alex Geerts
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.
Here is an example of how the error occurs.
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.
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"
__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.
__init__()
method.An alternative solution is to set a default value for the argument.
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.
__init__()
method, you can remove it and hardcode the value in the method.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.
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.
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.
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 ran every time it is invoked, so the issue no longer exists.