NameError: class is not defined when overriding a class in python

Question:

Why can’t python seem to find the InterfaceWithNoMenu class

class Settings(Screen):

        class SettingsWithNoMenu(kivy.uix.settings.SettingsWithNoMenu):

                def __init__(self, *args, **kwargs):
                        self.interface_cls = InterfaceWithNoMenu
                        kivy.uix.settings.SettingsWithNoMenu.__init__( self, *args, **kwargs )

        class InterfaceWithNoMenu(kivy.uix.settings.ContentPanel):
                def add_widget(self, widget):
                        if self.container is not None and len(self.container.children) > 0:
                                raise Exception(
                                'ContentNoMenu cannot accept more than one settings panel')
                        super(InterfaceWithNoMenu, self).add_widget(widget)
                        kivy.uix.settings.InterfaceWithNoMenu.__init__( self, *args, **kwargs )

        actionview = ObjectProperty(None)
        settings_content = ObjectProperty(None)

        def __init__(self, **kwargs):

                super(Settings, self).__init__(**kwargs)
...

I’m trying to change the look/feel/behaviour of the Settings module in a kivy-based python GUI app.

Unfortunately, when I create a settings window with the above program that creates an instance of the locally-overridden self.SettingsWithNoMenu class, I get the following error:

     self.interface_cls = InterfaceWithNoMenu
 NameError: name 'InterfaceWithNoMenu' is not defined

I don’t understand. It’s right there. I mean, the class InterfaceWithNoMenu is literally defined right underneath the one (SettingsWithNoMenu) that’s referencing it.

Why can’t the class SettingsWithNoMenu find InterfaceWithNoMenu? Why am I getting a NameError here?

Asked By: Michael Altfield

||

Answers:

You’re using the InterfaceWithNoMenu class before defining it, as you declare an instance of it in the SettingWithNoMenu class.

Can you swap those class definitions around and see if that fixes this error? (and you might need to make the reference more specific, with a self or a this or something)

Answered By: Noscere

InterfaceWithNoMenu is defined in the namespace of the Settings class, not the global or local namespace. You should be able to do:

self.interface_cls = Settings.InterfaceWithNoMenu

since Settings is available in the global namespace.

Nested class definitions are a little awkward IMO and I would usually recommend not using them, especially if there’s a dependency between "sibling" classes like this that requires the nested class to access its enclosing class.

Answered By: Samwise
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.