self"何时必需?

15 投票
3 回答
11299 浏览
提问于 2025-04-11 20:40

我最近才开始使用类,每次写方法的时候,我都会把所有的变量都用self来引用,比如self.foo。

不过,我在看《wxPython in Action》这本书的时候,发现并不是所有地方都用“self”。比如:

 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)

下面这个地方是用“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")

如果我没记错的话,“self”是指类的一个特定实例,那什么时候可以不使用它呢?有没有什么简单的规则可以遵循?

3 个回答

0

在提到实例本身时,self总是必需的,除了在调用基类构造函数(wx.Frame.__init)的时候。你在例子中看到的其他变量(比如panel、basicLabel、basicText等)只是局部变量——和当前对象没有任何关系。这些名字在方法返回时就会消失,而放在self.foo里的东西会在方法结束后继续存在,并且可以在下一个方法中使用(例如self.button)。

4

在这种情况下,如果你不使用 self,那么你只会创建一个局部变量,名字和你想要的变量一样。在第一个例子中,panel 被创建为一个局部变量,然后在函数中后面被引用,但它在函数外是无法使用的。把 self 传给 wx.Panel 的构造函数,就把它和当前对象关联起来了,这样它在函数返回后就不会消失。

9

你用 self.attribute 来引用当前实例的一个属性。

你用 wx.Frame.__init__() 来调用父类的方法。

如果你只是引用当前方法(函数)里的一个局部变量,就不需要用 self

这些不是“经验法则”,因为没有例外。


让你感到困惑的地方可能是,panel 似乎只是构造函数里的一个局部名字,所以看起来一旦构造函数结束,panel 就会消失。

不过,如果你查看 wx.Panel 的文档,你会发现它的构造函数会把 panel 绑定到父窗口上,这样即使构造函数结束后,panel 也会继续存在。

这就是魔法 :)

撰写回答