3

Say I have a custom class and an instance of it:

class Container:
    def __init__(self):
        self._modules = {}

container = Container()

Is it possible to override the from X import Y functionality so that I can do stuff like:

>>> container._modules['foo'] = 'bar'
>>> from container import foo
>>> foo
'bar'
Markus Meskanen
  • 19,939
  • 18
  • 80
  • 119

1 Answers1

2

There are solutions to this that use import hooks, defined in PEP 302 (similar question: https://stackoverflow.com/a/3074701/5764588), but here's a solution that overrides the builtin __import__-function with one that checks the local namespace for the x in from x import y:

I wouldn't recommend using this in any real scenarios though, since it's quite hackish, seeing as it's plugging in to python's core functionality, and could produce some confusing code when, for example, you have a module with the same name as the local variable. Your use case might be valid though, in which case, hack away!

class Container:

    def __init__(self):
        self._modules = {}

    def __getattr__(self, name):
        if name in self._modules:
            return self._modules[name]
        return super().__getattr__(name)

container = Container()
container._modules["foo"] = "bar"


prev_import = __import__

def new_import(name, globals=None, locals=None, fromlist=(), level=0):
    if level == 0 and fromlist and name in locals:
        return locals[name]

    return prev_import(name, globals, locals, fromlist, level)

__builtins__.__import__ = new_import


from container import foo

print(foo)
joelhed
  • 60
  • 6