2013-10-28 47 views
0

在Python 3我有这样的工作的:不同的实现在Python 2.7 __import __()和Python 3.x的

def aFunctionImportingAndCallingAnotherFunction(functionName, args): 
    packageString = "a_nested_package.to_be_imported.at_run_time" 
    _temp = __import__(packageString, globals(), locals(), [functionName], 0) 
    function = eval("_temp." + functionName) 
    return function(args) 

在Python 2.7我得到一个错误,我通过与功能functionName不存在。

在这个例子中,包装a_nested_packagesys.path,它有一个包to_be_imported,它有一个包at_run_time。所有软件包都有__init__.py文件。

我尝试:

  • 与水平参数播放(我想-1和1)
  • packageString
  • 除去a_nested_packagepackageString除去a_nested_package并用.
替换它

另外,如果这是完全错误的方法来执行运行时导入的函数,请让m知道!我非常新到Python(由C来++,PHP和Java)

+0

为什么你不使用['importlib'模块](http://docs.python.org/2/library/importlib.html)? –

+0

你真的想在这里做什么?动态导入模块,或者只是动态地在导入的模块中选择一个对象*。 –

+0

@MartijnPieters:因为我不知道它;-)我会尽快试一试。 – DudeOnRock

回答

3

使用importlib module动态导入模块,然后使用getattr()从该模块检索特定名称:

import importlib 

def aFunctionImportingAndCallingAnotherFunction(functionName, args): 
    module = importlib.import_module(packageString) 
    func = getattr(module, functionname) 
    return func(*args) 
+0

@DudeOnRock:啊,不,不管这句话,这是对事情的解释。我只是在Python 2.7和3.3上测试了这一点,它对我来说都很好。 –

+0

这很好理解,这可能意味着我的'sys.path'在两个版本中都不一样。谢谢一堆! – DudeOnRock

2

__import__作品就像import声明。 (有充分理由)

当你这样做:

import foo.bar.baz 

你并没有在文件中baz对象;你得到foo!同样,这样的:

__import__('foo.bar.baz') 

返回foo模块,但可以保证它已经填充了bar

所以在你的例子中,__import__返回a_nested_package,你必须自己遍历路径的其余部分。这很糟糕,这也是为什么importlib有用。 :)

+0

但是这两个python 2都是一样的。7和3.x,还是我误解了? – DudeOnRock

+0

这是一样的。唯一的区别是2.7中的'level'默认为-1,因此会尝试相关的导入,3.3+不支持。自己比较文档:[2.7](http://docs.python.org/2/library/functions.html#__import__),[3.3](http://docs.python.org/3/library/functions。 html #__ import__) – Eevee

+0

很酷,谢谢澄清,虽然! – DudeOnRock