KQS
KQS

Reputation: 1597

Import a Python module without adding it to the local namespace

What I'd like to do

I'd like to import a Python module without adding it to the local namespace.

In other words, I'd like to do this:

import foo
del foo

Is there a cleaner way to do this?

Why I want to do it

The short version is that importing foo has a side effect that I want, but I don't really want it in my namespace afterwards.

The long version is that I have a base class that uses __init_subclass__() to register its subclasses. So base.py looks like this:

class Base:
    _subclasses = {}

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        cls._subclasses[cls.__name__] = cls

    @classmethod
    def get_subclass(cls, class_name):
        return cls._subclasses[class_name]

And its subclasses are defined in separate files, e.g. foo_a.py:

from base import Base

class FooA(Base):
    pass

and so on.

The net effect here is that if I do

from base import Base

print(f"Before import: {Base._subclasses}")

import foo_a
import foo_b

print(f"After import: {Base._subclasses}")

then I would see

Before import: {}
After import: {'FooA': <class 'foo_a.FooA'>, 'FooB': <class 'foo_b.FooB'>}

So I needed to import these modules for the side effect of adding a reference to Base._subclasses, but now that that's done, I don't need them in my namespace anymore because I'm just going to be using Base.get_subclass().

I know I could just leave them there, but this is going into an __init__.py so I'd like to tidy up that namespace.

del works perfectly fine, I'm just wondering if there's a cleaner or more idiomatic way to do this.

Upvotes: 3

Views: 342

Answers (1)

Brian61354270
Brian61354270

Reputation: 14423

If you want to import a module without assigning the module object to a variable, you can use importlib.import_module and ignore the return value:

import importlib

importlib.import_module("foo")

Note that using importlib.import_module is preferable over using the __import__ builtin directly for simple usages. See the builtin documenation for details.

Upvotes: 3

Related Questions