开发者

Python calling class methods with the wrong number of parameters

I'm just beginning to learn python. I wrote an example script to test OOP in python, but something very odd has happened. When I call a class method, Python is calling the function with one more parameter than given.

Here is the code:


1.  class Bar:
2.   num1,num2 = 0,0
3.   d开发者_Go百科ef __init__(num1,num2):
4.    num1,num2 = num1,num2
5.   def foo():
6.    if num1 > num2:
7.     print num1,'is greater than ',num2,'!'
8.    elif num1 is num2:
9.     print num1,' is equal to ',num2,'!'
10.   else:
11.    print num1,' is less than ',num2,'!'
12. a,b = 42,84
13. t = Bar(a,b)
14. t.foo
15. 
16. t.num1 = t.num1^t.num2
17. t.num2 = t.num2^t.num1
18. t.num1 = t.num1^t.num2
19. 
20. t.foo

And the error message I get:


python test.py
Traceback (most recent call last):
  File "test.py", line 13, in 
t = Bar(a,b)
TypeError: init() takes exactly 2 arguments (3 given) 

Can anyone help?

Thanks in advance


The first argument passed to an instance method is the instance itself. Typically this is called self when defining the function:

  def __init__(self, num1, num2):

Consider reading the tutorial.


Couple things:

  1. Your class is named Bar but you're calling it as bar(a, b). Change that to Bar(a, b) to solve this problem.
  2. Classes need to inherit from something (if nothing, then object). You need class Bar(object):
  3. Instance methods, in Python, are always supplied one parameter, which is the object itself, before other passed parameters. So your def __init__(num1, num2): should be def __init__(self, num1, num2):, and the same for def foo().
  4. All of your instance variables need to be prefixed by self.. So num1 should be self.num1, etc.
  5. The ^ operator is boolean XOR. Not sure if this is what you want, it's often confused with the power operator, **.

Here's your example, cleaned up and fixed accordingly:

class Bar(object):
    num1, num2 = 0, 0
    def __init__(self, num1, num2):
        self.num1, self.num2 = num1, num2

    def foo(self):
        if self.num1 > self.num2:
            print self.num1,'is greater than ',self.num2,'!'
        elif self.num1 is self.num2:
            print self.num1,' is equal to ',self.num2,'!'
        else:
            print self.num1,' is less than ',self.num2,'!'

a, b = 42, 84
t = Bar(a, b)
t.foo()

t.num1 = t.num1 ^ t.num2
t.num2 = t.num2 ^ t.num1
t.num1 = t.num1 ^ t.num2

t.foo()

And the result:

42  is less than  84 !
84 is greater than  42 !


a) By convention, the first parameter of a method is called self.

b) On line 4 you are self-assigning. Maybe you want to say self.num1, self.num2

c) If you want to call the method foo of t (lines 14 and 20) you should add parentheses at the end: t.foo()

d) The indentation is idiomatically given by 4 spaces, which makes reading much easier.

EDIT: You might want to look at chapters 15-18 of Allen Downey's book "Think Python: How to Think Like a Computer Scientist". This book is very short, nicely written, and easy to read. It is freely available here.

EDIT2: I hadn't noticed this before, but as dash-tom-bang pointed out in a comment below, in this context it is best if (on line 8) you compared for equality using == instead of is.


In regards to that particular error message, you're missing the self argument on line 3. It should read:

def __init__(self, num1,num2):

Unlike instance methods in other OOP languages, in Python, you have to explicitly name the instance as the first argument when defining such a method. Then, when you call obj.some_method(), obj is automatically and implicitly passed as the first argument to some_method.

The first argument is idiomatically named self, but nothing is stopping you from naming it anything else.


Python identifiers are case-sensitive... bar != Bar...

Also, you need to explicitly declare self as the first argument of the __init__() method, something like:

def __init__(self, num1, num2):
   #...etc.

BTW, see bcherry's answer as he/she covers other typical Python beginner mistakes (such as not explicitly prefixing the instance variables with self....

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜