Calling a class method raises a TypeError in Python

143,862

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

Solution 5

You need to spend a little more time on some fundamentals of object-oriented programming.

This sounds harsh, but it's important.

  • Your class definition is incorrect -- although the syntax happens to be acceptable. The definition is simply wrong.

  • Your use of the class to create an object is entirely missing.

  • Your use of a class to do a calculation is inappropriate. This kind of thing can be done, but it requires the advanced concept of a @staticmehod.

Since your example code is wrong in so many ways, you can't get a tidy "fix this" answer. There are too many things to fix.

You'll need to look at better examples of class definitions. It's not clear what source material you're using to learn from, but whatever book you're reading is either wrong or incomplete.

Please discard whatever book or source you're using and find a better book. Seriously. They've mislead you on how a class definition looks and how it's used.

You might want to look at http://homepage.mac.com/s_lott/books/nonprog/htmlchunks/pt11.html for a better introduction to classes, objects and Python.

Share:
143,862
stu
Author by

stu

I love stackoverflow. It undoes years of work by google to automate the process of finding information and replacing it with a human effort. I call this progress.

Updated on July 14, 2022

Comments

  • stu
    stu almost 2 years

    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?

  • Nepho
    Nepho over 15 years
    Sorry for the downvote, but I think you misinterpreted the question. It seems that stu is new to Python, so directing him to good resources about Python basics is probably better than showing him how to use static methods ;)
  • rob
    rob over 15 years
    On another hand, the explicit usage of "self" in python and wrong beliefs on static methods are quite a common pitfall for people coming from other languages. As many here are pointing documentation and resources, I think there should be at least one "straight" reply. Thanks for the comment!
  • Abgan
    Abgan over 15 years
    Disagree. What is not mandatory is name of 'self'. But the first argument of Python member function is a reference to an object. Of course you have class and static methods, but for instance methods the rule applies.
  • nosklo
    nosklo over 15 years
    you can call it however you want. "self" is just a convention.
  • kampu
    kampu almost 11 years
    @Abgan: actually, it even applies for class and static methods -- the decorators just do some automangling so that the wrapped function receives different parameters than the wrapper.
  • Tim S.
    Tim S. over 9 years
    @JoshSmeaton You should use "self" really, because even though it's not technically required, it's a very standard convention and would make your code more mainstream with other python developers.
  • B Bulfin
    B Bulfin over 8 years
    The question is literally "what's wrong?" This answer does state what's wrong, so I'd argue it is an answer.
  • Eran Moshe
    Eran Moshe over 7 years
    Unless you're making a utility class which is fine to make alot of static and class methods
  • BLaZuRE
    BLaZuRE almost 7 years
    @recursive (Responding to 7 years later comment, 2 years later) I would argue the real question was in the title, which was literally "How to instantiate a class". Pointing out you need to create an instance when trying to learn how to create one is unhelpful; stating that it's an answer is pedantic based on the context (title). You didn't even elaborate or guide for a proper answer, someone else did for you. We were all new to programming and new to phrasing questions at some point.
  • DJ_Stuffy_K
    DJ_Stuffy_K about 6 years
    is it ok if we simply do myclass().average(a,b,c)?
  • cmoman
    cmoman about 6 years
    @DJ_Stuffy_K that code works for my first code example. But the original question related to instantiating the class so I included the def __init__() method. Your code snippet instantiates the class but there is no 'handle' left by which to access other methods that might use the same instance variables. Perhaps that helps.
  • Veronica Cheng
    Veronica Cheng about 6 years
    This link is not working now.. Can I have the course/book name instead?