__init__() missing 1 required positional argument it reads self as a parameter - python

I'm new at programming and I'm learning Python. The code should be very simple. The goal should be implement a calculator that does additions between numbers.
It returns this error:
init() missing 1 required positional argument: 'number_2'
So it's like it reads self as a parameter, but I can't figure out why.
I'm using Linux Ubuntu 19 as operative system.
Here's my code:
class Calculator:
def __init__(self, number_1, number_2):
self.number_1=number_1
self.number_2=number_2
def add(self):
print(f"{number_1}+{number_2}={number_1+number_2}")
if __name__=="__main__":
c=Calculator('Casio')
c.add(2,3)

It isn't reading self as a parameter here, but 'Casio' which it is storing as number_1. As the error message reads, it is missing number 2. If you want add() to be able to take arbitrary values, you will need to add them as arguments to that method rather than to the __init__() function.

You have to pass parameters to the add function and not to __init__ which instantiates the class.
class Calculator:
def __init__(self, name):
self.name=name
def add(self, number_1, number_2):
print(f"{number_1}+{number_2}={number_1+number_2}")
if __name__=="__main__":
c=Calculator('Casio')
c.add(2,3)

When you are initializing the object 'c', you are running the init method, and you therefore need to pass in both parameters to the init method. So, you are required to give both 'number_1' and 'number_2' when you create the object. You passed in only'Casio', which python is interpreting as 'number_1'. Python is also interpreting that there is no 'number_2'. Here are some solutions:
1: You could make the add() function have the two arguments that init has ('number_1' and 'number_2') and have the only arguments for init be self and 'name'. Then, you could have the init method only do self.name = name and nothing else. 2: You could make the arguments 'number_1' and 'number_2' optional by making a default variable for them if you do not enter it:
def __init__(self, number_1="1", number_2="2"):

Related

python function behaves differently

Declaring a class with method 'print' with param 'self':
class First:
def print(self):
print('working')
return 2
Trying to call the method without instantiating the class:
First.print() getting below message:
TypeError: print() missing 1 required positional argument: 'self'
Now when instantiating the class and accessing the method: it's working.
first = First()
first.print()
# working
# 2
Now defining the same class without any param in method print:
class First:
def print():
print('working')
return 2
Calling the same method without instantiating the class and it's working:
First.print()
# working
# 2
Without defining the method param, python method behaving like Static. Is it true or something else?
self refers to the bound variable or object. so it needs instantiation. where as without self method becomes static (class method in python context) and can be called using Class Name.
Also you should write #classmethod decorator above the method definition. so that it is clearly state that it is a classmethod.
class First:
#classmethod
def print(cls):
print('working')
return 2
First.print()
For your reference
https://medium.com/quick-code/understanding-self-in-python-a3704319e5f0
In the first case, it is a function of one parameter. So, Class.f() fails. In the second example, it is a function of zero parameters. So, Class.f() works.
When you create an instance, the first parameter is automatically bound to that instance, and you need to pass n-1 parameters. So, it works in your first example, but it won't work in your second.

How self variable works,when class is assigned to instance variables

I came across following piece of code in robot framework.
variable are assigned with different class name.
https://github.com/robotframework/robotframework/blob/master/src/robot/variables/variables.py
def __init__(self):
self.store = VariableStore(self)
self._replacer = VariableReplacer(self)
self._finder = VariableFinder(self.store)
To understand how does above assignment work,i wrote following piece of code,which is throwing error when using self
class Foo(object):
def __init__(self):
pass
def addition(self):
return 5
class boo(object):
def __init__(self):
self.word = Foo(self)
def multiply(self):
return self.word.addition()
if __name__ == '__main__':
b = boo()
print(b.multiply()) #TypeError: __init__() takes 1 positional argument but 2 were given
When using following combination in boo() class,getting the correct output i.e. 5.
self.word=Foo;return self.word.addition(self)
self.word=Foo();return self.word.addition()
The issue is def __init__(self) inside the Foo class. You have as the parameter self, but, just like any other method, it doesn't have to be specifically passed in. So in the boo constructor, when you say self.word = Foo(self), you're actually calling __init__ of Foo with two arguments; the inherent self and the self of boo you're passing. That explains why you're getting the error of __init__() takes 1 positional argument but 2 were given.
There are a couple things wrong with your interpretation of what is happening. First, let's look at the code and the error you're getting:
b = boo()
print(b.multiply()) #TypeError: __init__() takes 1 positional argument but 2 were given
Your comment seems to imply you think the error is happening when you call b.multiply(). However, when you look at the stack trace you'll see it happens when you do b = boo():
Traceback (most recent call last):
File "/tmp/junk.py", line 16, in <module>
b = boo()
File "/tmp/junk.py", line 10, in __init__
self.word = Foo(self)
TypeError: __init__() takes 1 positional argument but 2 were given
Note that the stack trace is telling you precisely what the problem is. You've defined Foo.__init__ to take a single parameter but two are being given. Why are two being given? When you create an instance of a class in python, python automatically passes in the self parameter. In other words, if you do b=boo(), your function will automatically get self without you having to explicitly pass it in. This is a very fundamental part of python's design. It has nothing to do with robot framework.
In trying to replicate the robot code, you've created a class named Foo that takes a single parameter named self. However, the VariableStore object takes two parameters: self and variables:
class VariableStore(object):
def __init__(self, variables):
...
Remember, python will automatically pass in self, so the first argument you pass in will get associated with the variables parmeter.
Consider this line of code:
self.store = VariableStore(self)
Based on how VariableStore is defined, it is exactly the same as this:
self.store = VariableStore(variables=self)
Notice how self is not the same as the self parameter of the __init__. It is passed to the variables parameter. This is because python automatically passes self as the first parameter when constructing a class.

Method in class will not take arguments

I am new to Python and I am just trying to make a simple class to test it out. I used the self argument while defining my method in the "Patient" class but I am still getting the "takes no arguments error" when I try to build. Here is the code I'm trying to run...
class Patient:
def _init_(self,name,weight=0,LegLen=0):
self.name = name
self.weight = weight
self.LegLen = LegLen
Mark = Patient('Mark')
print(Mark.name)
then I get the error...
Mark = Patient('Mark')
TypeError: Patient() takes no arguments
What am I doing wrong?
The _init_ should be spelled __init__ (double underscores). Otherwise it's just a method like any other and not a constructor.

TypeError: __init__() takes 4 positional arguments but 7 were given

class Employee(object):
def __init__(self,ename,salary,dateOfJoining):
self.ename=ename
self.salary=salary
self.dateOfJoining=dateOfJoining
def output(self):
print("Ename: ",self.ename,"\nSalary: ",self.salary,"\nDate Of
Joining: ",self.dateOfJoining)
class Qualification(object):
def __init__(self,university,degree,passingYear):
self.university=university
self.degree=degree
self.passingYear=passingYear
def qoutput(self):
print("Passed out fom University:",self.university,"\nDegree:",self.degree,"\Passout year: ",self.passingYear)
class Scientist(Employee,Qualification):
def __int__(self,ename,salary,dateOfJoining,university,degree,passingYear):
Employee.__init__(self,ename,salary,dateOfJoining)
Qualification.__init__(self,university,degree,passingYear)
def soutput(self):
Employee.output()
Qualification.output()
a=Scientist('Ayush',20000,'21-04-2010','MIT','B.Tech','31-3-2008')
a.soutput()
I'm not able to get a solution to the problem and I'm not able to understand why this TpyeError has occured. I'm new to python. Thanks
Your scientist class has the init function written as :
def __int__
instead of
def __init__
So what happened is it inherited the init function from its parent class, which receives less params then you sent to the class.
Also instead of calling the init of the parents you should be using the super function.
super(PARENT_CLASS_NAME, self).__init__()
This obviously goes for all parent functions.
Your Scientist class constructor is misspelled as __int__ instead of __init__. Since there is no overridden constructor to be used from the Scientist class, it goes up a level on the inheritance chain and uses the Employee's constructor, which in fact only uses 4 positional arguments. Just fix the typo and it should work.
(there are a few other bad things you're doing with classes in your code, but I'll allow other people to comment with tips)

Error - __init__() takes exactly 2 arguments (1 given)

I'm trying to initialize the class (extraropt) from another .py but it gives me an error, I've searched but I haven't found a solution.
Heres the code of the one py I'm calling from:
main.py:
class GameWindow(ui.ScriptWindow):
def __init__(self, stream):
import extraop
exec 'extraop.extraropt().Show(stream)'
And here's the code of the one py I'm trying to call(init and del only):
extraop.py
class extraropt(ui.Window):
def __init__(self, stream):
ui.Window.__init__(self)
self.BuildWindow()
self.stream=stream
def __del__(self):
ui.Window.__del__(self)
It gives this error:
Error - __init__() takes exactly 2 arguments (1 given)
In the line
exec 'extraop.extraropt().Show(stream)'
You are implicitly calling extraropt.__init__() by creating a new instance of extraopt. In your code, you show that extraropt.__init__() takes a second (stream) argument, so you have to pass that in.
extraop.extraropt(stream).Show()
Incidentally, there is no reason why you should be doing an exec rather than explicitly calling it as I did above. There is also no reason for you to have a __del__() method defined as you only call the parent __del__() method anyway.
You need to initialize the parent this way:
super(extraropt, self).__init__(stream)
The stream variable in the line exec 'extraop.extraropt().Show(stream)' should be passed into the constructor of the extraropt class, like this:
exec 'extraop.extraropt(stream).Show()'

Categories

Resources