[Python] Importing multiple modules containing identically named class in python

Discussão em 'Python' iniciado por Stack, Abril 2, 2025.

  1. Stack

    Stack Membro Participativo

    I would like to import optional GUI elements defined in separate .py files and add/remove these dynamically from the main GUI. The optional elements are defined in a text configuration file and thus the file names are not known in advance. My original idea was to impose a common format - the main class would be identically named in all module files. I found that the simplest implementation of this behaves in an unexpected way. Although the imported objects appear to have distinct names, there is in fact cross-talk. This demonstrates the issue and a workaround that I found on SE (commented out):

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.button import Button
    from kivy.lang import Builder
    import importlib

    Builder.load_string('''
    <MainWidget>:
    orientation: 'vertical'
    BoxLayout:
    Button:
    text: "Load Mod 1"
    on_press:
    root.load_module(self.text)
    Button:
    text: "Load Mod 2"
    on_press:
    root.load_module(self.text)
    Button:
    text: "Unload all"
    on_press:
    dock.clear_widgets()
    FloatLayout:
    id: dock
    ''')

    class MainWidget(BoxLayout):

    def load_module(self, hint):

    self.ids.dock.clear_widgets()

    if "1" in hint:
    self.module = importlib.import_module("Mod1").Module()#PROBLEMATIC
    #module = importlib.import_module("Mod1")
    #class_ = getattr(module, "Module1")
    #self.module = class_()
    if "2" in hint:
    self.module = importlib.import_module("Mod2").Module()#PROBLEMATIC
    #module = importlib.import_module("Mod2")
    #class_ = getattr(module, "Module2")
    #self.module = class_()

    self.ids.dock.add_widget(self.module)

    class MyApp(App):
    def build(self):
    return MainWidget()

    if __name__ == '__main__':
    MyApp().run()


    Mod1.py:

    from kivy.uix.floatlayout import FloatLayout
    from kivy.lang import Builder

    Builder.load_string('''
    #<Module1>:
    <Module>: #PROBLEMATIC
    size_hint: None, None
    size: self.parent.size if self.parent else self.size
    pos: self.parent.pos if self.parent else self.pos
    Button:
    size_hint: None, None
    width: self.parent.width / 3
    height: self.parent.height
    pos: self.parent.pos
    text: "Mod 1"
    on_press: print(root); print([x for x in dir(root) if 'method' in str(x)])
    ''')

    #class Module1(FloatLayout):
    class Module(FloatLayout): #PROBLEMATIC

    def __init__(self, **kwargs):
    super(FloatLayout, self).__init__(**kwargs)

    def dummymethod1(self):
    pass


    Mod2.py:

    from kivy.uix.floatlayout import FloatLayout
    from kivy.lang import Builder

    Builder.load_string('''
    #<Module2>:
    <Module>: #PROBLEMATIC
    size_hint: None, None
    size: self.parent.size if self.parent else self.size
    pos: self.parent.pos if self.parent else self.pos
    Button:
    size_hint: None, None
    width: self.parent.width / 3
    height: self.parent.height
    pos: (self.parent.x + self.parent.width / 2) , self.parent.y
    text: "Mod 2"
    on_press: print(root); print([x for x in dir(root) if 'method' in str(x)])
    ''')

    #class Module2(FloatLayout):
    class Module(FloatLayout): #PROBLEMATIC

    def __init__(self, **kwargs):
    super(FloatLayout, self).__init__(**kwargs)

    def dummymethod2(self):
    pass


    It appears that although the modules have distinct names Mod1 and Mod2, the main class having the same name is a problem. Once both modules have been imported at least once, both appear in the GUI regardless which one is actually activated. [​IMG]

    Although my workaround works to prevent this unwanted behaviour, I would like to know what causes it. Is this to do with how importing works in Python in general, or a Kivy specific issue? Is there another way to deal with this that would allow for identically-names classes in otherwise distinct modules?

    Continue reading...

Compartilhe esta Página