1

I have a couple modules loaded on startup. Every module has a name and a send function. To access the imported modules I store them in a dict and access by the dict key.

m1 = Module1()
m2 = Module2()
modules = {m1.name: m1, m2.name: m2}
# now access a function
modules["m1_name"].send()

this approach works pretty well but seems a bit ugly to me. Is there an "official" way?

EDIT: I define a list of priorities, say prios = ["signal", "telegram", "txt"], the program tries to send the message to each user of a group, always trying to use the module with highest priority. Only modules in the prio list will be imported.

EDIT: my import function looks like this:

for modul_name in prios:
    modul_import = importlib.import_module(("modules." + modul_name))
    modul = modul_import.Modul(self.inbox)
    modul.start()
    modules[modul_name] = modul
apacar
  • 13
  • 6
  • 2
    Why not access the modules using the modules themselves instead of via the hardcoded `name`? How is it that other modules know the hardcoded name of each module - that seems to break encapsulation and seems like a code/design smell. – yangmillstheory Apr 03 '16 at 21:15

2 Answers2

0

Are you accessing m1 and m2 from the same module that imports it in your example? If so, it seems unnecessarily indirect to access it by name.

Otherwise, having m1, and m2 in the importing module's scope makes it accessible to other modules importing that module, in which case you can just access it using the module objects themselves which is more direct and Pythonic - see this pattern.

You might want to declare these exports explicitly and hide the rest of m1 and m2 like

__all__ = ['m1_send', 'm2_send']

m1_send = m1.send
m2_send = m2.send

Finally, are you sure you're not duplicating __name__ with your name? Search __name__ in the docs here.

yangmillstheory
  • 1,055
  • 13
  • 31
0

Could you give an example of how you use modules dictionary? Is it necessary to call send function indirectly giving module name?

Anyway your approach is clean for me but maybe you would prefer to use AttrDict described here: Accessing dict keys like an attribute in Python?

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self


modules = AttrDict(m1.__name__=m1, m2.__name__=m2)

modules.m1.send()
modules.m2.send()
Community
  • 1
  • 1
apr
  • 370
  • 1
  • 5
  • Code is snippet is wrong, and [in violation of PEP 8](https://www.python.org/dev/peps/pep-0008/#other-recommendations) with regards to keyword argument spacing. There's also no guarantee that `m1.__name__` is the same as `m1_name`. – yangmillstheory Apr 03 '16 at 21:28