1

I started learning classes in python and wanted to build a simple calculator like so:

import math

class calculator:
    def plus(self, num1, num2):
        plus = num1 + num2
        print plus
    def minus(self, num1, num2):
        minus = num1 - num2
        print minus
    def power(self, num1, num2):
        power = math.pow(num1, num2)
        return power

C = calculator

num1 = raw_input("1st num > ")
num2 = raw_input("2nd num > ")

C.minus(num1, num2)

But for some reason when I run the script it shows me an error stating "unbound method minus() must be called with calculator instance as first argument (got str instance instead)". I don't really understand what does this mean but I did try to play with the script and nothing changed. so what am I missing here?

Kulyuly
  • 43
  • 4
  • 1
    You need to make a instance of calculator, like: C = calculator() –  May 18 '16 at 17:34

1 Answers1

5

You did not create an instance of your class:

C = calculator

C is now just a reference to the class, making C.minus an unbound method.

Create an instance instead by calling your class:

C = calculator()

Alternatively, make all your functions @staticmethods, removing their self parameter (but do inherit from object in that case):

class calculator(object):
    @staticmethod
    def plus(num1, num2):
        plus = num1 + num2
        print plus
    @staticmethod
    def minus(num1, num2):
        minus = num1 - num2
        print minus
    @staticmethod
    def power(num1, num2):
        power = math.pow(num1, num2)
        return power

Now your calculator class is a glorified namespace which is generally frowned upon. If you are not going to use a class for tracking per-instance state, you may as well make all those staticmethods top-level functions in a module instead, and avoid having to 'unbind' your methods.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Frowned upon by whom? Do you have a reference? –  May 18 '16 at 17:40
  • 1
    @DavidCullen It's less flexible than using modules and doesn't gain you anything, I don't think a reference is necessary. – Peter Wood May 18 '16 at 17:42
  • @PeterWood: I understand why it is frowned upon. However, I think it is generally frowned upon to make that kind of statement in a StackOverflow answer without providing a reference. –  May 18 '16 at 17:45
  • @DavidCullen: You'd normally use a module for this. That documents the intent far better; why have the full infrastructure for a class *anyway* if you are never going to instantiate it and have to bypass the descriptor mechanism just to get functions again? – Martijn Pieters May 18 '16 at 17:45
  • @DavidCullen: [Is it a good idea to using class as a namespace in Python](http://stackoverflow.com/q/3576596) – Martijn Pieters May 18 '16 at 17:45
  • @MartijnPieters: I am not arguing your point. However, your answer would be improved if you provided a reference. –  May 18 '16 at 17:47
  • @DavidCullen Martijn can pretty much serve as his own reference. I'm not quite sure what sort of reference you're looking for - something directly from the BDFL's mouth? A blog post? – MattDMo May 18 '16 at 19:37