views:

346

answers:

3

I have been using classes for only a short while and when I write a method, I make all variables reference self, e.g. self.foo.

However, I'm looking through the wxPython in Action book and notice that "self" isn't used all the time. For example:

 import wx
 class TextFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Text Entry Example',
            size=(300, 100))
        panel = wx.Panel(self, -1)
        basicLabel = wx.StaticText(panel, -1, "Basic Control:")
        basicText = wx.TextCtrl(panel, -1, "I've entered some text!",
            size=(175, -1))
        basicText.SetInsertionPoint(0)
        pwdLabel = wx.StaticText(panel, -1, "Password:")
        pwdText = wx.TextCtrl(panel, -1, "password", size=(175, -1),
            style=wx.TE_PASSWORD)
        sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
        sizer.AddMany([basicLabel, basicText, pwdLabel, pwdText])
        panel.SetSizer(sizer)

The one below does use "self".

import wx
class ButtonFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'Button Example',
            size=(300, 100))
        panel = wx.Panel(self, -1)
        self.button = wx.Button(panel, -1, "Hello", pos=(50, 20))
        self.Bind(wx.EVT_BUTTON, self.OnClick, self.button)
        self.button.SetDefault()
    def OnClick(self, event):
        self.button.SetLabel("Clicked")

If I remember correctly, "self" is reference to a particular instance of the class, so when is it not necessary? Is there a general rule of thumb?

+4  A: 

In those instances, if you do not use self then you will create only a local variable of that name. In the first example, panel is created as a local variable and then referenced later in the function, but it won't be available outside that function. The act of passing self to the wx.Panel constructor associated it with the current object in some fashion, so it doesn't just disappear when the function returns.

Greg Hewgill
wx.Frame.__init__ references the method of the parent class wx.Frame
hop
To build on this, I'd say prefer a local variable to an instance variable (i.e. don't use self) unless you really need to keep a reference to the object for later use in the class (e.g. as ButtonFrame.OnClick uses self.button). Minimising variable scope often makes debugging and maintenance easier.
Sam Stokes
Okay. That makes sense.
crystalattice
A: 

self is always required when referring to the instance itself, except when calling the base class constructor (wx.Frame.__init__). All the other variables that you see in the examples (panel, basicLabel, basicText, ...) are just local variables - not related to the current object at all. These names will be gone when the method returns - everything put into self.foo will survive the end of the method, and be available in the next method (e.g. self.button).

Martin v. Löwis
wx.Frame.__init__ does not reference the instance, so it is not an exception!
hop
+5  A: 

You use self.attribute to reference an attribute of your current instance.

You use wx.Frame.__init__() to reference a method of the parent class.

You don't use self if you only reference a local name (variable) of the method (function) you are in.

These are not "rules of thumb," because there are no exceptions.


What is probably confusing you in this particular example is that panel seems to be only a local name in the constructor, so it looks like the panel would disappear, once your constructor returns.

If you look at the documentation to wx.Panel, though, you will see that its constructor attaches the panel to the parent window, so it will continue to exist, even after the constructor returns.

Magic :)

hop
+1: Not "rules of thumb". Just rules.
S.Lott