'self' parameter in Python non-class functions
<p>I'm currently teaching some basic Python to an eager primary school student, and I'm having a bit of trouble wrapping my head around a strange little anomaly in this code for an etch-a-sketch.</p>

<pre><code># 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("&lt;Up&gt;", p1_move_N)
window.bind("&lt;Down&gt;",p1_move_S)
window.bind("&lt;Left&gt;", p1_move_W)
window.bind("&lt;Right&gt;", p1_move_E)
window.bind("&lt;u&gt;", erase_all)

window.mainloop()
</code></pre>

<p>The player controls are what's bugging me. The code doesn't work if I don't have <code>self</code> added. I get:</p>

<pre><code>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
</code></pre>

<p>I've done a bit of research and found that <code>self</code> is used for class methods. As you can see, none of the functions are class methods. The only thing I can think of is that <code>bind()</code> treats all functions passed to it as class methods, meaning they require <code>self</code> to function correctly.</p>

<p>Any and all help is appreciated.</p>

<p>The callable passed to <code>bind</code> takes one argument: event. So, the correct way to define the function is e.g.:</p>

<pre><code>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
</code></pre>

<p><code>Tk</code> is going to pass one positional argument, so you are free to call the argument anything you want (<code>self</code> works, yes, and <code>banana</code> would work as well).</p>

<p>See also <a href="https://docs.python.org/2/library/tkinter.html#bindings-and-events" rel="nofollow">the documentation for Tk event binding</a>.</p>

python class tkinter key-bindings