Python:函数需要 1 个位置参数,但给出了 2 个,如何?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23842770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python: function takes 1 positional argument but 2 were given, how?
提问by 648trindade
I was creating a Sudoku Game in python with Tk.
我正在用 Tk 在 python 中创建一个数独游戏。
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)
和这个错误/异常 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
I don't mind where is the error. I have included the self on my function
我不介意错误在哪里。我已经在我的函数中包含了 self
采纳答案by gnasr
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),
假设您的方法 kk 用于多个位置,并且您不想发送一些随机变量来占用如下所示的“another_parameter”位置(根据 Christian 的响应进行处理),
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:
就个人而言,我认为参数列表应该只有他们需要的。因此,只要您不需要 bind() 函数发送的“another_parameter”变量,我建议通过执行以下操作来使用 Lambda:
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
我认为您现在需要 kk 后面的两个括号,因为 lambda 实际上将使用它的参数运行该函数(在您的情况下,如果您删除我所说的那个,就不会有)。lambda 为我们做的是捕获从 bind 函数抛出到 kk 的参数(即 'e' 在 lambda 之后,它代表参数)。现在,我们的参数列表中不需要它了,我们可以恢复我们的 kk 定义为
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.
我开始使用 Christian 的方法(有效!)但我不喜欢额外的变量。显然这两种方法都有效,但我认为这一种有帮助,特别是如果在 bind 中调用的函数被多次使用并且不一定被绑定调用使用。
回答by Christian
I'm not a tkinter
expert, but it seems (by what I've read so far) that the method
我不是tkinter
专家,但似乎(根据我目前阅读的内容)该方法
bind(some_string, some_function)
calls function
passing the parameter string
to it.
调用function
将参数传递string
给它。
You have declared the method kk
like
你已经声明了kk
这样的方法
def kk(self):
and it means that it is only expecting one argument. You are also passing the method self.kk
to bind()
, which means that it will be called like
这意味着它只期待一个论点。您还将方法传递self.kk
给bind()
,这意味着它将被调用
self.kk('<KeyPress-2>')
There is the problem! That call, in fact, is passing two arguments to the method kk
. It's equivalent to
问题来了!实际上,该调用将两个参数传递给方法kk
。它相当于
sudoku.kk(janela, '<KeyPress-2>')
Note that janela
is the actual instance of the class sudoku
. Coming back to the problem, you are passing two arguments!!!
请注意,这janela
是类的实际实例sudoku
。回到问题上来,你传递了两个参数!!!
How can you solve it?
你怎么解决?
As I said I'm not an expert on this topic, but my guess is to declare the method kk
with two parameters:
正如我所说,我不是这个主题的专家,但我的猜测是kk
用两个参数声明方法:
def kk(self, another_parameter):
# ...
Note:I would recommend you to follow Python naming conventions. In other words, class names should be like SomeClassName
or Sudoku
.
注意:我建议您遵循Python 命名约定。换句话说,类名应该像SomeClassName
or Sudoku
。
回答by Sadjad
You need to define kk
function as this:
您需要将kk
函数定义为:
def kk(self, event):
lb[0][0]['text']='2'
Because you're binding kk
to a key press event, and it is automatically passed the event object (which has some useful information about the event), so kk
need to have another argument, event
, other than self
.
因为您绑定kk
到按键事件,并且它会自动传递事件对象(其中包含有关该事件的一些有用信息),所以kk
需要有另一个参数event
,而不是self
.
回答by Bartosz Marcinkowski
Change kk
definition to
将kk
定义更改为
def kk(self, event):
...
then when you pass self.kk
as callback, tk
will call it like func(event)
(self.kk(event)
) and everything will be fine.
然后当你self.kk
作为回调传递时,tk
会像func(event)
( self.kk(event)
)一样调用它,一切都会好起来的。
Now when tk
calls func(event)
, which is like self.kk(event)
, the number of arguments is wrong.
现在,当tk
调用 时func(event)
,就像 一样self.kk(event)
,参数的数量是错误的。