2012-11-12 22 views
2

我有一个字符串type,其值为“MBSquareObject”。 MBSquareObject是名为MBObject的文件中的类。我想动态导入MBSquareObject从字符串中用Python导入模块

如果正方形物体在它自己的文件,这个工程:

__import__(type) 

不过,我想要做的是from MBObject import MBSquareObject等同。但是,这不起作用:

from MBObject __import__(type) 

我还能怎么做?

编辑:给出的答案假定MBSquareObject是MBObject上的某种对象,但它只是另一个类。 MBSquareObject是MBObject的一个子类,因此它们被列在同一个文件中。

编辑:由于某种原因,没有答案正在工作。下面是我有:

# 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() 

错误:NameError:名字 'MBSquareObject' 没有定义

回答

4

你举的例子表明该模块名称MBObject不需要被动态访问,只有内部的对象。在这种情况下,你可以做

import MBObject 
thing = getattr(MBObject, type) 

编辑:一个问题是,你是给你的模块和类的名称相同,因此很难区分它们在你的代码。你在类和模块之间感到困惑。你有两个东西叫做MBObject。一个是模块,另一个是该模块内的类。当你做from MBObject import MBObject时,你需要导入这个类,但是不要引用这个模块,这使得后续从同一个模块中导入第二个类(MBSquartObject)变得很笨拙。

你可以得到你想要用我上面给的代码的效果,但你必须from MBObject import MBObject ---当你这样做,你不给自己的模块的引用,只有类在该模块中。相反,只需执行import MBObject,然后通过MBObject.MBObject访问MBObject类。

如果您希望能够引用同一模块中的MBObject类和其他类,而不用模块名称作为前缀,请为该模块指定一个不同的名称。 Python风格指南建议在MixedCase中以小写字母和类命名模块。所以命名你的模块mbobject.py。然后你可以这样做:

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

一般来说,在模块和类中给Python命名并不是一个好主意。模块和类是不同的东西,并给他们相同的名称可能导致这样的混乱,你不清楚你是否在处理模块或类。

+0

等待对不起,我应该指定:MBSquareObject是一个类,MBObject的一个子类。他们只是放在同一个文件中。 – Snowman

+0

@mohabitar文件叫什么?如果它被命名为'MBObject.py',那么这应该工作。在这种情况下,MBObject指的是模块名称,而不是类名称。 –

+0

@mohabitar:在这种情况下,您需要编辑您的问题以更清楚地解释您要做的事情。 '从MBObject导入MBSquareObject'将从一个名为'MBObject'的*模块导入一个东西(类,数字,字符串等等)。你知道你想要导入的模块的名称,还是必须动态确定,如果是这样,如何? (也就是说,你是从模块中单独确定模块还是以某种方式链接?) – BrenBarn

0

如何:

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

__import__可以采用额外的参数指定应该导入哪些对象。从这个函数的返回中,你可以获取你想要的任何对象。

source_module = 'MBObject' 
object_in_module = 'MBSquareObject' 

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

这也不起作用。请参阅编辑 – Snowman

+0

'__import__'返回导入的模块 - 您需要存储该返回值,如示例中所示。导入不会自动添加到全局范围(为此,'从x导入y'将工作得很好)。 –

+0

所以我会用它来代替'object_class = eval(type)'? – Snowman

1

__import__功能的完整语法描述the documentation

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

这里fromlist是要从导入的模块导入的项目列表。像

from module import object1, object2 

的声明是作为像

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

所以你的情况,你可以使用

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

在最新版本的Python,因为3.1,有一个模块importlib你可以用它来做到这一点。虽然我能找到的唯一方法是使用模块的实现__import__,这与内置实现基本相同,所以我想你可能会使用内置实现。

+0

我试过这个,但它不工作。请参阅编辑 – Snowman

+0

不,这不是你试过的。或者至少你编辑成你的问题不是任何答案告诉你做的。在你说它不工作之前,尝试使用我给你的代码。 –

+0

这可能是此主题中最优雅的解决方案。 –