Python非类函数中的'self'参数

时间:2016-09-22 23:48:00

标签: python class tkinter key-bindings

我目前正在向一位热心的小学生讲授一些基本的Python,而且我在这段代码中围绕着一个奇怪的小异常包围着蚀刻草图时遇到了一些麻烦。

# myEtchASketch application

from tkinter import *

#####Set variables
canvas_height = 400
canvas_width=600
canvas_colour="black"

p1_x=canvas_width/2
p1_y=canvas_height
p1_colour="blue"
line_width=6
line_length=9

####New window
window=Tk()
window.title("MyEtchASketch")
canvas=Canvas(bg=canvas_colour, height=canvas_height, width=canvas_width,highlightthickness=0)
canvas.pack()

##### Functions:

#player controls
def p1_move_N(self):
    global p1_y
    canvas.create_line(p1_x, p1_y, p1_x, (p1_y-line_length), width=line_width, fill=p1_colour)
    p1_y = p1_y - line_length

def p1_move_S(self):
    global p1_y
    canvas.create_line(p1_x, p1_y, p1_x, (p1_y+line_length), width=line_width, fill=p1_colour)
    p1_y=p1_y+line_length

def p1_move_W(self):
    global p1_x
    canvas.create_line(p1_x, p1_y, (p1_x-line_length), p1_y, width=line_width, fill=p1_colour)
    p1_x=p1_x-line_length

def p1_move_E(self):
    global p1_x
    canvas.create_line(p1_x, p1_y, (p1_x+line_length), p1_y, width=line_width, fill=p1_colour)
    p1_x=p1_x+line_length

def erase_all(self):
    canvas.delete(ALL)


#bind movement to key presses
window.bind("<Up>", p1_move_N)
window.bind("<Down>",p1_move_S)
window.bind("<Left>", p1_move_W)
window.bind("<Right>", p1_move_E)
window.bind("<u>", erase_all)

window.mainloop()

玩家控制是什么让我烦恼。如果我没有添加self,则代码无效。我明白了:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\ThisIsNotMyRealUserFolder\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
TypeError: p1_move_N() takes 0 positional arguments but 1 was given

我做了一些研究,发现self用于类方法。如您所见,这些函数都不是类方法。我唯一能想到的是bind()将所有传递给它的函数视为类方法,这意味着它们需要self才能正常运行。

感谢任何和所有帮助。

1 个答案:

答案 0 :(得分:0)

传递给bind的callable接受一个参数:event。因此,定义函数的正确方法是:。

def p1_move_W(event):
    global p1_x
    canvas.create_line(p1_x, p1_y, (p1_x-line_length), p1_y, width=line_width, fill=p1_colour)
    p1_x=p1_x-line_length

Tk将传递一个位置参数,因此您可以随意调用参数(self有效,是的,banana也可以。)< / p>

另见the documentation for Tk event binding