2016-09-22 2 views
-2

현재 초등 중학교 학생에게 기본적인 Python을 가르치고 있습니다.이 코드에서 이상한 작은 예외를 감안하여 머리를 감싸는 데 어려움을 겪고 있습니다. 에치 - 스케치.Python 비 클래스 함수의 'self'매개 변수

# 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이 필요합니다.

모든 도움을 주시면 감사하겠습니다.

+0

셀프는 변수 이름을 나타냅니다. 자아를 모두 x로 바꿀 수 있고 여전히 작동해야합니다. 메서드는 여전히 1 매개 변수가 전달 될 것으로 예상하기 때문에 코드가 "self"없이 작동하지 않습니다 (또는 호출 될 때 atleast - 1 개의 변수가 전달됨) – AK47

+2

'self'인수를 호출했으나 이름. 여기에서 진짜 문제는 tkinter가 콜백에 전달하고자하는 인수를 이해하지 못한다는 것입니다. [그것에 대해 읽으십시오.] (http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm) – user2357112

+0

@tehjoker : _ "Self는 변수 이름을 나타냅니다." 아니. 현재 객체에 대한 참조이지만 클래스의 메소드 인 경우에만 해당합니다 (그렇지 않은 경우). –

답변

0

bind에게 건네지는 호출 가능 항목은 event라는 하나의 인수를 취합니다. 당신이 인수 당신이 원하는 무엇이든 (self 작품을 자유롭게 호출 할 수 있습니다 있도록

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

네, 하나 개의 위치 인수를 전달하는 것입니다, 그리고 banana과 같이 작동합니다 : 그래서, 함수를 정의하는 올바른 방법은 예입니다 잘).

도 참조하십시오. the documentation for Tk event binding.

+0

나는 '자기'가 절대로 작동하지 않는다고 말할 것이다. 엄밀히 말하면 작동하지만 이름이 오해의 소지가있어 이해하기 쉽고 유지 보수가 어려운 코드로 이어집니다. –