2013-10-28 45 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