Search code examples
pythonkivyoverridingnameerror

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


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?


Solution

  • 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.