Python: функция принимает 1 позиционный аргумент, но 2 даны, как?

Я создавал игру Sudoku в python с Tk.

Я получил ошибку о функции нажатия клавиши для кнопки

from random import randint from tkinter import * class sudoku: global root,result,lb def __init__(self): self.aleatoriedade() for k in range(9): j=randint(0,80) x=j//9 y=j-(x*9) lb[x][y]['text']=result[x][y] lb[0][0].bind('<KeyPress-2>',self.kk) #setted this for test root.mainloop() def kk(self): lb[0][0]['text']='2' def aleatoriedade(self): for i in range(9): var=0 while var in result[0]: var=randint(1,9) result[0][i]=var for i in range(1,9): for j in range(9): result[i][j]=result[0][field[i][j]-1] #MAIN() n = 3 field = [[(i*n + i//n + j) % (n*n) + 1 for j in range(9)]for i in range(9)] result = [[None for i in range(9)]for i in range(9)] lb=[[None for i in range(9)]for i in range(9)] x=0 y=0 root=Tk() for i in range(9): for j in range(9): lb[i][j]=Button(root,font=("Verdana",'13',"bold"),bd=1,height=3,width=6) if (i in (0,1,2,6,7,8) and j in (0,1,2,6,7,8))or(i in (3,4,5) and j in (3,4,5)): lb[i][j]['bg']='white' lb[i][j].grid(row=i,column=j) janela=sudoku() 

и эта ошибка / исключение в lb[0][0].bind('<KeyPress-2>',self.kk)

 Exception in Tkinter callback Traceback (most recent call last): File "C:\Python33\lib\tkinter\__init__.py", line 1489, in __call__ return self.func(*args) TypeError: kk() takes 1 positional argument but 2 were given 

Я не против, где ошибка. Я включил себя в свою функцию

4 Solutions collect form web for “Python: функция принимает 1 позиционный аргумент, но 2 даны, как?”

Я вижу, что на это был дан ответ, но у меня есть способ, который я действительно предпочитаю, и что вы и другие можете оценить.

Скажем, что ваш метод kk используется во многих местах, и вы не хотите отправлять какую-либо случайную переменную, чтобы занять место «another_parameter», показанное ниже (отработка ответа Христиана),

 def kk(self, another_parameter): 

Лично я считаю, что списки параметров должны иметь ТОЛЬКО то, что им нужно. Поэтому, если вам не нужна переменная «another_parameter», которую посылает функция bind (), я предлагаю использовать Lambda, выполнив следующие действия:

 lb[0][0].bind('<KeyPress-2>',lambda e:self.kk()) 

Думаю, вам нужны две скобки после kk, потому что lambda на самом деле будет запускать эту функцию с ее параметрами (в вашем случае, если вы удалите тот, который я сказал, не будет). То, что лямбда делает для нас, – это улавливать параметр, который бросается в kk из функции связывания (это то, что «e» находится после лямбда, оно представляет аргумент). Теперь нам это не нужно в нашем списке параметров, и мы можем возобновить наше определение kk

 def kk(self): 

Я начал использовать подход Кристиана (который работает!), Но мне не понравилась дополнительная переменная. Очевидно, что оба метода работают, но я думаю, что это помогает, особенно если функция, вызываемая в bind, используется более одного раза и не обязательно используется вызовом bind.

Я не эксперт tkinter , но кажется (по тому, что я до сих пор читал), что метод

 bind(some_string, some_function) 

вызывает function передающую ему string параметров.

Вы объявили метод kk like

 def kk(self): 

и это означает, что он ожидает только один аргумент . Вы также передаете метод self.kk для bind() , что означает, что он будет вызываться как

 self.kk('<KeyPress-2>') 

Есть проблема! Этот вызов, по сути, передает два аргумента методу kk . Это эквивалентно

 sudoku.kk(janela, '<KeyPress-2>') 

Обратите внимание, что janela является фактическим экземпляром класса sudoku . Возвращаясь к проблеме, вы передаете два аргумента !!!

Как вы можете это решить?

Как я уже сказал, я не специалист по этой теме, но я предполагаю, что объявить метод kk с двумя параметрами:

 def kk(self, another_parameter): # ... 

Примечание. Я бы рекомендовал вам следовать соглашениям об именах Python . Другими словами, имена классов должны быть похожими на SomeClassName или Sudoku .

Вам нужно определить функцию kk следующим образом:

 def kk(self, event): lb[0][0]['text']='2' 

Поскольку вы привязываете kk к событию нажатия клавиши, и он автоматически передает объект события (который содержит некоторую полезную информацию о событии), поэтому kk должен иметь другой аргумент, event , отличное от self .

Измените определение kk на

 def kk(self, event): ... 

то, когда вы передаете self.kk качестве обратного вызова, tk назовет его как func(event) ( self.kk(event) ), и все будет хорошо.

Теперь, когда tk вызывает func(event) , что похоже на self.kk(event) , количество аргументов неверно.

  • Окно Tkinter фокусируется на Mac OS X
  • Почему параметр Button «команда» выполняется при объявлении?
  • Список Python Tkinter
  • Базовый таймер обратного отсчета Tkinter
  • Pickle не будет работать с tkinter
  • Python 3 и tkinter открывают новое окно, нажимая кнопку
  • Tkinter понимает mainloop
  • Значок изменения в окне фигуры Matplotlib
  • Использовать графический интерфейс для открытия каталога в Python 3
  • tkinter - Как установить шрифт для текста?
  • Как получить текст метки Tkinter?
  • Python - лучший язык программирования в мире.