3

I was trying to do something like this:

module.py

def __getitem__(item):
    return str(item) + 'Python'

test.py

import module
print module['Monty']

I expected "MontyPython" to be printed. However, this doesn't work:

TypeError: 'module' object is not subscriptable 

Is it possible to create a subscriptable module in pure Python (i.e. without modifying its source code, monkey-patching, etc.)?

Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
Pastafarianist
  • 833
  • 11
  • 27
  • I am writing an app that needs access to a certain global state from various places. I thought it would be cool to have something like: `import state; state[something_specific] = new_stuff` than `from state_class import state; ...` – Pastafarianist May 03 '12 at 21:05
  • I dont think the coolness is worth the effort. Just go ahead with the *dot* syntax. In my opinion it is much more better. – cobie May 03 '12 at 21:08

1 Answers1

5
>>> class ModModule(object):
    def __init__(self, globals):
        self.__dict__ = globals
        import sys
        sys.modules[self.__name__] = self
    def __getitem__(self, name):
        return self.__dict__[name]


>>> m = ModModule({'__name__':'Mod', 'a':3})
>>> import Mod
>>> Mod['a']
3

# subclassing the actual type won't work
>>> class ModModule(types.ModuleType):
    def __init__(self, globals):
        self.__dict__ = globals
        import sys
        sys.modules[self.__name__] = self
    def __getitem__(self, name):
        return self.__dict__[name]


>>> m = ModModule({'__name__':'Mod', 'a':3})

Traceback (most recent call last):
  File "<pyshell#114>", line 1, in <module>
    m = ModModule({'__name__':'Mod', 'a':3})
  File "<pyshell#113>", line 3, in __init__
    self.__dict__ = globals
TypeError: readonly attribute

you may use ModModule(globals()) to replace the current module in sys.

User
  • 14,131
  • 2
  • 40
  • 59