1

Sorry for the generic title, will change it once I understand the source of my problem I have the following structure:

foo/
foo/__init__.py
foo/bar/
foo/bar/__init__.py
foo/bar/some_module.py

When I try to import some_module by doing so:

from foo.bar import some_module

it works like a charm. But this is no good for me, since I only know the name of the module to import in runtime. so if I try:

from foo.bar import *
mod=__import__('some_module')

I get an error. Am I doing something wrong? Is there a better way to do this? and why is this happening?

Why is that? I am not quite sure I completely understand the concept behind python packages. I thought they were equivalent to java's packages and thus

2
  • 3
    What does the error message say? Commented Aug 27, 2009 at 16:14
  • 2
    your some_module is already imported! Commented Aug 27, 2009 at 16:17

3 Answers 3

7

I believe the proper way to do this is:

mod = __import__('foo.bar', fromlist = ['some_module'])

This way even the 'foo.bar' part can be changed at runtime. As a result some_modulewill be available as mod.some_module; use getattr if you want it in a separate variable:

the_module = getattr(mod, 'some_module')
Sign up to request clarification or add additional context in comments.

Comments

1
from foo.bar import *

is a bad practice since it imports some_module into the global scope.

You should be able to access your module through:

import foo.bar
mod = getattr(foo.bar, 'some_module')

It can be easily demonstrated that this approach works:

>>> import os.path
>>> getattr(os.path, 'basename')
<function basename at 0x00BBA468>
>>> getattr(os.path, 'basename\n')
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    getattr(os.path, 'basename\n')
AttributeError: 'module' object has no attribute 'basename
'

P.S. If you're still interested in using your kind of import statement. You need an eval:

from foo.bar import *
eval('some_module')

To clarify: not only it's bad practice to use *-import it's even worse in combination with eval. So just use getattr, it's designed exactly for situations like yours.

7 Comments

-1 for recommending eval(). Always use globals()['some_module'] instead if all you want is to look up the value from global scope.
All right, +1 again for your clarification. getattr() is the right answer here. If you need to use __import__(), see kurczak's answer.
Uh oh, now I get "Vote too old to be changed, unless this answer is edited". My apologies -- I saw eval() in a code block and automatically clicked -1.
sorry, this doesn't seem to work... doing this raise an error: 'module' object has no attribute 'some_module' (Dunno why it refers to foo.bar as a module...)
It works perfectly, it just means that foo.bar doesn't have attribute some_module. Where are you getting the name from?
|
0

From the docs:

Direct use of __import__() is rare, except in cases where you want to import a module whose name is only known at runtime.

However, the dotted notation should work:

mod = __import__('foo.bar.some_module')

Comments

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.