views:

62

answers:

3

Hello,

I have this superclass:

import wx

class Plugin(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        wx.Panel.__init__(self, parent, *args, **kwargs)
        self.colorOver = ((89,89,89))
        self.colorLeave = ((110,110,110))
        self.SetBackgroundColour(self.colorLeave)
        self.SetForegroundColour(self.colorLeave)
        self.name = "plugin"

        wx.StaticText(self, -1, self.getName(), style=wx.ALIGN_LEFT)


        self.Bind(wx.EVT_ENTER_WINDOW, self.onMouseOver)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.onMouseLeave)

    def onMouseOver(self, event):
        self.SetBackgroundColour(self.colorOver)
        self.Refresh()

    def onMouseLeave(self, event):
        self.SetBackgroundColour(self.colorLeave)
        self.Refresh()

    def OnClose(self, event):
        self.Close()
        app.Destroy()

    def getName(self):
        return self.name

and this subclass:

import plugin
import wx

class noisePlugin(plugin.Plugin):
    self.name = "noise"

and it gives me this error compiling the subclass:

Traceback (most recent call last):
  File "C:\Users\André Ferreira\Desktop\Tese\Código Python\SoundLog\Plugins\noisePlugin.py", line 4, in <module>
    class noisePlugin(plugin.Plugin):
  File "C:\Users\André Ferreira\Desktop\Tese\Código Python\SoundLog\Plugins\noisePlugin.py", line 5, in noisePlugin
    self.name = "noise"
NameError: name 'self' is not defined

What can I do to fix this error? I want getName() method to return the name of the instanciated class!

Thanks in advance :)

+3  A: 

Make the subclass

class noisePlugin(plugin.Plugin):
    def __init__(self, *a, **k):
        plugin.Plugin.__init__(self, *a, **k)
        self.name = "noise"

Whenever you want to use self.something you have to be within a method, not at class level outside of methods!

Alex Martelli
thanks m8 :) it was exactlly that!
aF
@aF, glad to have been of help!-)
Alex Martelli
A: 

What makes you think this works?

class noisePlugin(plugin.Plugin):
    self.name = "noise"

Why didn't you copy the

class Plugin(wx.Panel):
    def __init__(self, parent, *args, **kwargs):

That comes before self.name=?

S.Lott
A: 

For the pattern you seem to be trying for (where the name is associated more with the class than with the instance), this is often a better idiom to follow:

class A(object):
    name = 'parent'

    def __init__(self, ...):
       ... etc

class B(A):
    name = 'child'

    def __init__(self, ...):
        A.__init__(self, ...)
        ... etc

Even though the name attribute is stored on the class rather than the instance, you can access it using self.name in all the instances. Generally if you find yourself assigning a static (unchanging) attribute that is the same in all instances of a given class you should just use a static class attribute like this.

On a slightly different topic, were you aware that all wxPython widgets already have a name attribute, which can be assigned using the name keyword argument at initialization time, and accessed using either GetName() or (in recent versions of wxPython) the property Name? If you don't assign it, it will default to some fairly generic class-specific value (like "text" or "textctrl" for wx.TextCtrl). Depending on what you're trying to do, maybe you can just use it instead of your own name and getName(). wxPython itself does not make any use of this value, as it's intended for you the programmer to use as you see fit.

Peter Hansen