Python - difference between self.method, lambda: self.method() and self.method() on startup
<p>In order to understand the difference in use of method calls, I wrote a MVC in python 2.7. Here is the code:</p>

<pre><code>import Tkinter as tk

class Model(object):
    def __init__(self, *args, **kwargs):
        # dict
        self.data = {}
        # -- &gt;values
        self.data["Value_One"] = tk.IntVar()
        self.data["Value_Two"] = tk.IntVar()
        self.data["Value_Three"] = tk.IntVar()
        # --&gt; texts
        self.data["Text_Label_val_One"] = tk.StringVar()
        self.data["Text_Label_val_Two"] = tk.StringVar()
        self.data["Text_Label_val_Three"] = tk.StringVar()

class Control(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs) # init
        tk.Tk.wm_title(self, "Testing Grounds") # title

        self.model = Model()
        self.view = View(parent = self, controller = self)
        self.view.pack(fill = 'both', expand = True)

    def set_labels_text(self):
        self.model.data["Text_Label_val_One"].set("Value_One is set to: {0}".format(self.model.data["Value_One"].get()))
        self.model.data["Text_Label_val_Two"].set("Value_Two is set to: {0}".format(self.model.data["Value_Two"].get()))
        self.model.data["Text_Label_val_Three"].set("Value_Three is set to: {0}".format(self.model.data["Value_Three"].get()))

    def set_value_one(self):
        self.model.data["Value_One"].set(1)    

    def set_value_two(self):
        self.model.data["Value_Two"].set(2)

    def set_value_three(self):
        self.model.data["Value_Three"].set(3)

class View(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        self.buttons()
        self.labels()

    def buttons(self):
        set_v_one = tk.Button(self, text = "Set Value One To 1", command = lambda: self.controller.set_value_one())
        set_v_one.pack(fill = 'x', expand = True)

        set_v_two = tk.Button(self, text = "Set Value Two To 2", command = self.controller.set_value_two())
        set_v_two.pack(fill = 'x', expand = True)

        set_v_three = tk.Button(self, text = "Set Value Three To 3", command = self.controller.set_value_three)
        set_v_three.pack(fill = 'x', expand = True)

        update_lbl_two = tk.Button(self, text = "Update Labels", command = self.controller.set_labels_text)
        update_lbl_two.pack(fill = 'x')

    def labels(self):
        label_one = tk.Label(self, textvariable = self.controller.model.data["Value_One"])
        label_one.pack(fill = 'x', expand = True)

        label_two = tk.Label(self, textvariable = self.controller.model.data["Value_Two"])
        label_two.pack(fill = 'x', expand = True)

        label_three = tk.Label(self, textvariable = self.controller.model.data["Value_Three"])
        label_three.pack(fill = 'x', expand = True)        

        label_val_one = tk.Label(self, textvariable = self.controller.model.data["Text_Label_val_One"])
        label_val_one.pack(fill = 'x', expand = True)

        label_val_two = tk.Label(self, textvariable = self.controller.model.data["Text_Label_val_Two"])
        label_val_two.pack(fill = 'x', expand = True)

        label_val_three = tk.Label(self, textvariable = self.controller.model.data["Text_Label_val_Three"])
        label_val_three.pack(fill = 'x', expand = True)

if __name__ == "__main__":
    app = Control()
    app.mainloop()
</code></pre>

<p>If one executes it and hits the button to update the labels, the result is the following:</p>

<p><a href="http://i.stack.imgur.com/GIRrD.jpg" rel="nofollow"><img src="http://i.stack.imgur.com/GIRrD.jpg" alt="enter image description here"></a></p>

<p>As one can see, <code>model.self.data["Value_One"]</code> is not set on startup, due to the use of <code>lambda</code>, which I thought to be a nameless function, which can only return one value and nothing more. Here it seems to inhibit the initial call of the method by the command line of button <code>set_v_one</code>.</p>

<p>In the case of <code>model.self.data["Value_Two"]</code>, the value is updated on startup. I'd think thats because the function is called, when the command line of the button is read and the button created, due to the active call or initialization of the method via brakets <code>()</code>, because it does happen, even when one doesn't pack the button.</p>

<p>For <code>model.self.data["Value_Three"]</code>, the value is also not updated on startup. This is, as I'd think, caused by the method <code>set_value_three(self)</code> of the controller bound to the command line, but not initialized, due to the lack of calling for it by using the brakets <code>()</code>.</p>

<p>After pressing the buttons <code>set_v_one</code> and <code>set_v_three</code>, the values get properly updated, as indicated by the corresponding labels <code>label_one</code> and <code>label_three</code>. </p>

<p>Even though I'm using these method calls a lot, I couldn't yet fully understand, how they work in detail. If someone could clarify this or point me to a good source I just haven't found yet, it would be much appreciated.</p>

<p>All in all, there is no mystery here. </p>

<p>The command argument of the Button constructor takes a callback, i.e. a function that will be executed when the button is pressed. You do this for buttons 1 and 3. So when the corresponding buttons are clicked, the function (be it the lambda or the bound method) is called and the labels are updated. With button two, you actually execute the method that sets the value of the second label and assigning the command argument the result of that method call (which will be None). This is in violation of the API as far as I understand and should probably result in an error. </p>

<p>To sum it up, your confusion seems to stem from mixing up a function (an object that can be executed) and its invocation (the action of executing a function). </p>

python lambda method-call