Calling a class method raises a TypeError in Python
I don't understand how classes are used. The following code gives me an error when I try to use the class.
class MyStuff:
def average(a, b, c): # Get the average of three numbers
result = a + b + c
result = result / 3
return result
# Now use the function `average` from the `MyStuff` class
print(MyStuff.average(9, 18, 27))
Error:
File "class.py", line 7, in <module>
print(MyStuff.average(9, 18, 27))
TypeError: unbound method average() must be called with MyStuff instance as first argument (got int instance instead)
What's wrong?
Solution 1:
You can instantiate the class by declaring a variable and calling the class as if it were a function:
x = mystuff()
print x.average(9,18,27)
However, this won't work with the code you gave us. When you call a class method on a given object (x), it always passes a pointer to the object as the first parameter when it calls the function. So if you run your code right now, you'll see this error message:
TypeError: average() takes exactly 3 arguments (4 given)
To fix this, you'll need to modify the definition of the average method to take four parameters. The first parameter is an object reference, and the remaining 3 parameters would be for the 3 numbers.
Solution 2:
From your example, it seems to me you want to use a static method.
class mystuff:
@staticmethod
def average(a,b,c): #get the average of three numbers
result=a+b+c
result=result/3
return result
print mystuff.average(9,18,27)
Please note that an heavy usage of static methods in python is usually a symptom of some bad smell - if you really need functions, then declare them directly on module level.
Solution 3:
To minimally modify your example, you could amend the code to:
class myclass(object):
def __init__(self): # this method creates the class object.
pass
def average(self,a,b,c): #get the average of three numbers
result=a+b+c
result=result/3
return result
mystuff=myclass() # by default the __init__ method is then called.
print mystuff.average(a,b,c)
Or to expand it more fully, allowing you to add other methods.
class myclass(object):
def __init__(self,a,b,c):
self.a=a
self.b=b
self.c=c
def average(self): #get the average of three numbers
result=self.a+self.b+self.c
result=result/3
return result
a=9
b=18
c=27
mystuff=myclass(a, b, c)
print mystuff.average()
Solution 4:
Every function inside a class, and every class variable must take the self argument as pointed.
class mystuff:
def average(a,b,c): #get the average of three numbers
result=a+b+c
result=result/3
return result
def sum(self,a,b):
return a+b
print mystuff.average(9,18,27) # should raise error
print mystuff.sum(18,27) # should be ok
If class variables are involved:
class mystuff:
def setVariables(self,a,b):
self.x = a
self.y = b
return a+b
def mult(self):
return x * y # This line will raise an error
def sum(self):
return self.x + self.y
print mystuff.setVariables(9,18) # Setting mystuff.x and mystuff.y
print mystuff.mult() # should raise error
print mystuff.sum() # should be ok