Last updated: Apr 8, 2024
Reading time·7 min
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('Bobby Hadz') print(emp1.name) # 👉️ "Bobby Hadz"
__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(repr(emp1.name)) # 👉️ "" emp2 = Employee('Bobby Hadz') print(emp2.name) # 👉️ "Bobby Hadz"
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.
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.
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"
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'
.
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 and 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 run every time it is invoked, so the issue no longer exists.
The error also occurs when forgetting to pass arguments to a second class when instantiating it.
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.
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
We passed a value for the name
argument to solve the error.
You can also use the super()
method to instantiate the parent class.
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.
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.
Here is an example of how the error occurs.
# 👇️ 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.
One way to solve the error is to provide a value for the arguments.
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.
2
arguments, we have to provide values for the arguments when the function is called.An alternative solution is to set default values for the function's parameters.
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.
If you are simply hard coding values for these arguments, you can remove the arguments and declare variables in the body of the function.
def do_math(): a = 100 b = 200 return a + b result = do_math() print(result) # 👉️ 300
We hardcoded the values for a
and b
.
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.
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.
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.
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.
You can learn more about the related topics by checking out the following tutorials: