何时需要使用"self"?

15

我只使用类很短的时间,当我编写一个方法时,我会让所有变量都引用self,例如self.foo。

然而,我正在阅读《wxPython实战》这本书,发现并不总是使用"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"是对类的特定实例的引用,那么它什么时候不必要呢?有没有一个经验法则?


重复问题:https://dev59.com/GnVD5IYBdhLWcg3wKYP- - S.Lott
兄弟,我怎么搜索不到这些之前的问题呢?这已经是第六次发生了。谢谢你给的链接。 - crystalattice
3个回答

9
您使用self.attribute来引用当前实例的属性。
您使用wx.Frame.__init__()来引用父类的方法。
如果您仅引用方法(函数)中的局部名称(变量),则不使用self
这些不是“经验法则”,因为没有例外。
在这个特定的例子中,可能会让您感到困惑的是,面板似乎只是构造函数中的一个局部名称,因此它看起来像是一旦构造函数返回,该面板将消失。
但是,如果您查看wx.Panel的文档,您将看到它的构造函数将面板附加到父窗口上,因此即使构造函数返回后,它也将继续存在。
神奇 :)

4
在这些情况下,如果你不使用 self ,那么你只会创建一个同名的局部变量。在第一个例子中,panel 被创建为一个局部变量,然后在函数后面被引用,但是它在函数外是不可用的。将 self 传递给 wx.Panel 构造函数与当前对象相关联,因此当函数返回时,它不会消失。

wx.Frame.init 引用了父类 wx.Frame 的方法。 - user3850
在此基础上,我会建议尽可能使用局部变量而非实例变量来构建代码(即不要使用self),除非您确实需要在类中稍后使用该对象的引用(例如,ButtonFrame.OnClick使用self.button)。最小化变量作用域通常使调试和维护更容易。 - Sam Stokes

0

在引用实例本身时,除了调用基类构造函数(wx.Frame.__init__)之外,总是需要使用self。您在示例中看到的所有其他变量(panel、basicLabel、basicText等)都只是局部变量 - 与当前对象无关。这些名称将在方法返回时消失 - 放入self.foo的所有内容将在方法结束后保留,并在下一个方法中可用(例如self.button)。


wx.Frame.__init__不引用实例,因此它不是异常! - user3850

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接