Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
976 views
in Technique[技术] by (71.8m points)

class - Python: function takes 1 positional argument but 2 were given, how?

I was creating a Sudoku Game in python with Tk.

I got a error about the function on a keypress for a button

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

and this error/exception in lb[0][0].bind('<KeyPress-2>',self.kk)

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

I don't mind where is the error. I have included the self on my function

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I see that this has been answered, but I have a way I really prefer and that you and others may appreciate.

Say that your method kk is used in multiple spots, and you don't want to have to send in some random variable to take up the spot of "another_parameter" shown below (working off of Christian's response),

def kk(self, another_parameter):

Personally, I think parameter lists should have ONLY what they need. So, as long as you have no need for the "another_parameter" variable that the bind() function sends, I suggest using Lambda by doing the following:

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

I think you need the two parentheses after kk now because lambda is actually going to run that function with it's parameters (in your case, if you remove the one I said to, there would be none). What lambda is doing for us is catching the parameter being thrown to kk from the bind function (that is what the 'e' is after lambda, it represents the argument). Now, we don't need it in our parameter list, and we can resume our kk definition to be

def kk(self):

I started using the approach by Christian (which works!) but I didn't like the extra variable. Obviously both methods work, but I think this one helps, especially if the function being called in bind is used more than once and not necessarily used by a bind call.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...