Python вызывает методы класса с неправильным количеством параметров - PullRequest
1 голос
/ 14 апреля 2010

Я только начинаю изучать питон.Я написал пример сценария для проверки ООП на python, но произошло нечто очень странное.Когда я вызываю метод класса, Python вызывает функцию с еще одним параметром, чем указано.

Вот код:


1.  class Bar:
2.   num1,num2 = 0,0
3.   def __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

И сообщение об ошибке, которое я получаю:


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

Может кто-нибудь помочь?
Заранее спасибо

Ответы [ 5 ]

7 голосов
/ 14 апреля 2010

Первый аргумент, передаваемый методу экземпляра, - это сам экземпляр. Обычно это называется self при определении функции:

  def __init__(self, num1, num2):

Подумайте над прочтением учебника .

5 голосов
/ 14 апреля 2010

Пара вещей:

  1. Ваш класс называется Bar, но вы называете его bar(a, b). Измените это на Bar(a, b), чтобы решить эту проблему.
  2. Классы должны что-то наследовать (если ничего, то object). Вам нужно class Bar(object):
  3. Методы экземпляра в Python всегда предоставляют один параметр, который является самим объектом, перед другими переданными параметрами. Таким образом, ваш def __init__(num1, num2): должен быть def __init__(self, num1, num2):, и то же самое для def foo().
  4. Все ваши переменные экземпляра должны иметь префикс self.. Так что num1 должно быть self.num1 и т. Д.
  5. Оператор ^ является логическим XOR. Не уверен, что это то, что вам нужно, его часто путают с оператором питания, **.

Вот ваш пример, очищенный и исправленный соответствующим образом:

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()

И результат:

42  is less than  84 !
84 is greater than  42 !
3 голосов
/ 14 апреля 2010

а) По соглашению первый параметр метода называется self.

б) В строке 4 вы назначаете себя. Может быть, вы хотите сказать self.num1, self.num2

в) Если вы хотите вызвать метод foo of t (строки 14 и 20), вам следует добавить скобки в конце: t.foo ()

d) Отступы идиоматически задаются четырьмя пробелами, что значительно облегчает чтение.

РЕДАКТИРОВАТЬ: Возможно, вы захотите взглянуть на главы 15-18 книги Аллена Дауни "Думай Python: Как думать, как ученый компьютер". Эта книга очень короткая, хорошо написана и легко читается. Он находится в свободном доступе здесь .

РЕДАКТИРОВАТЬ2: Я не замечал этого раньше, но, как указал даш-том-бэнг в комментарии ниже, в этом контексте лучше, если (в строке 8) вы сравниваете равенство, используя == вместо is.

1 голос
/ 14 апреля 2010

Что касается этого конкретного сообщения об ошибке, в строке 3 отсутствует аргумент self. Он должен выглядеть следующим образом:

def __init__(self, num1,num2):

В отличие от методов экземпляра в других языках ООП, в Python вы должны явно указывать экземпляр в качестве первого аргумента при определении такого метода. Затем, когда вы вызываете obj.some_method(), obj автоматически и неявно передается в качестве первого аргумента some_method.

Первый аргумент идиоматически называется self, но ничто не мешает назвать его чем-либо еще.

1 голос
/ 14 апреля 2010

Идентификаторы Python чувствительны к регистру ... bar! = Bar ...

Кроме того, вам необходимо явно объявить себя в качестве первого аргумента метода __init__(), что-то вроде:

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

Кстати, см. Ответ bcherry, поскольку он / она покрывает другие типичные ошибки новичка в Python (например, нет явного префикса переменных экземпляра с self. ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...