18

As discussed here, we can dynamically import a module using string variable.

import importlib
importlib.import_module('os.path')

My question is how to import * from string variable?

Some thing like this not working for now

importlib.import_module('os.path.*')
2
  • 2
    Why are you trying to do this? *-imports are generally frowned upon, they clutter the namespace and you may end up importing things you did not intend (e.g. a module is updated, gets a new function that overrides an earlier import). Do you have a concrete usecase for doing this dynamically? Commented Jun 12, 2017 at 7:07
  • I know using import * sound dangerous; though it works for simple use case. My concrete usecase is that I'm trying to use proboscis to run python test which allow me to pick up which test suit to run - the chosen test suit is defined by an array of test filenames. Commented Jun 12, 2017 at 7:18

1 Answer 1

26

You can do the following trick:

>>> import importlib
>>> globals().update(importlib.import_module('math').__dict__) 
>>> sin
<built-in function sin>

Be warned that makes all names in the module available locally, so it is slightly different than * because it doesn't start with __all__ so for e.g. it will also override __name__, __package__, __loader__, __doc__.

Update:

Here is a more precise and safer version as @mata pointed out in comments:

module = importlib.import_module('math')

globals().update(
    {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') 
    else 
    {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')
})

Special thanks to Nam G VU for helping to make the answer more complete.

Sign up to request clarification or add additional context in comments.

10 Comments

This will also import things like __name__, __package__, __loader__, __doc__ etc. which you definitely do not want imported.
more than a sin
if not k.startswith('_') would probably be better. The real import machinery when doing a * import also checks if the module has an __all__ attribute and only imports what is given there.
Thanks for the trick! Looks better now, I just skipped __all__ to make it a bit short snippet but your advice is good enough also to hide functions start with _
Something in the line of module = importlib.import_module('math'); globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')}), only formatted nicer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.