2

I have a string type with a value of "MBSquareObject". MBSquareObject is class in a file called MBObject. I want to import MBSquareObject dynamically.

If the square object was in a file of its own, this works:

__import__(type)

However, what I want to do is the equivalent of from MBObject import MBSquareObject. However, this doesn't work:

from MBObject __import__(type)

How else could I do this?

Edit: the answers given are assuming that MBSquareObject is some sort of object on MBObject, but it's just another class. MBSquareObject is a subclass of MBObject, so they are listed in the same file.

Edit: for some reason none of the answers are working. Here's what I have:

# this is imported at the top of the file
from MBObject import MBObject
type = 'MBSquareObject'
__import__('MBObject', globals(), locals(), [type])
object_class = eval(type)
object = object_class()

Error: NameError: name 'MBSquareObject' is not defined

0

5 Answers 5

4

Your example indicates that the module name MBObject doesn't need to be accessed dynamically, only the object inside. In that case, you can just do

import MBObject
thing  = getattr(MBObject, type)

Edit: One problem is that you are giving your module and class the same name, which makes it difficult to distinguish them in your code. You're getting confused between classes and modules. You have two things called MBObject. One is a module, the other is a class inside that module. When you do from MBObject import MBObject, you import the class, but give yourself no reference to the module, making it awkward to subsequently import a second class (MBSquartObject) from the same module.

You can get the effect you want by using the code I gave above, but you must not do from MBObject import MBObject --- when you do that, you don't give yourself a reference to the module, only the class in that module. Instead, just do import MBObject and then access the MBObject class via MBObject.MBObject.

If you want to be able to refer to both the MBObject class and other classes from the same module without prefixing them with the module name, give the module a different name. Python style guidelines advise naming modules in all lowercase and classes in MixedCase. So name your module mbobject.py. Then you can do:

import mbobject
from mbobject import MBObject
thing = getattr(mbobject, type)

In general it is not a good idea in Python to give the same name to a module and a class. Modules and classes are different things, and giving them the same name can lead to confusions like this where you're not clear on whether you're dealing with the module or the class.

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

9 Comments

Wait I'm sorry I should have specified: MBSquareObject is a class, a subclass of MBObject. They are just placed in the same file.
@mohabitar what is the file called? If it is named MBObject.py, then this should work. In this case MBObject refers to the module name, not the class name.
@mohabitar: In that case you need to edit your question to explain more clearly what you're trying to do. from MBObject import MBSquareObject will import a thing (class, number, string, whatever) from a module called MBObject. Do you know the name of the module you're trying to import from, or does that also have to be determined dynamically, and if so, how? (That is, are you determining the module separately from the class, or are they somehow linked?)
@DavidZaslavsky the name of the file is MBObject.py, and it has two classes: MBObject and MBSquareObject(subclass of MBObject)
@mohabitar: Have you already imported the MBObject class before you try to do the dynamic import? If so, maybe don't do that. (This is one reason why it's often not a good idea to give Python classes the same name as their module.) Please edit your question to give the complete context of your code.
|
3

__import__ can take additional arguments specifying exactly which objects should be imported. From the return of this function you can fetch whatever object you desire.

source_module = 'MBObject'
object_in_module = 'MBSquareObject'

obj = getattr(__import__(source_module, globals(), locals(), [object_in_module]),
              object_in_module)

4 Comments

__import__ returns the imported module — you need to store that return value as in the example. The import won't be automatically added to the global scope (for that, from x import y would work just fine).
So I would use that instead of object_class = eval(type)?
Yes. You can wrap the getattr call around the __import__ call to fetch the exact object within the module and nothing else.
It neither works here. I guess you can not use __import__ inline like that. The answer below by David Z, provides a similar, but functional, solution.
1

The full syntax of the __import__ function is described in the documentation:

 __import__(name[, globals[, locals[, fromlist[, level]]]])

Here fromlist is the list of items to import from the imported module. A statement like

 from module import object1, object2

is implemented as something like

module = __import__('module', globals(), locals(), ['object1', 'object2'])
object1 = getattr(module, 'object1')
object2 = getattr(module, 'object2')

So in your case, you could use

module = __import__('MBObject', globals(), locals(), [type])
the_object = getattr(module, type)

In recent versions of Python, since 3.1, there is a module importlib which you can presumably use to do this. Though the only way I can find to do so is to use the module's implementation of __import__, which is basically the same as the built-in implementation, so I guess you might as well use the built-in one.

1 Comment

No, this is not what you tried. Or at least what you edited into your question is not what any of the answers are telling you to do. Try actually using the code I've given you before you say it's not working.
1

Try this:

module = __import__('MSObject', globals(), locals(), ['MBSquareObject'], -1)

Plugged together using the examples found here:

http://docs.python.org/2/library/functions.html#import

Comments

0

How about:

module = __import__('MSObject.' + 'MBSquareObject')

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.