簡體   English   中英

Python的__import__不能按預期工作

[英]Python's __import__ doesn't work as expected

當使用__import__時,類似於: somepackage.somemodule ,返回的模塊不是somemodule ,返回的內容似乎大部分都是空的! 這里發生了什么?

__import__上的python文檔中:

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

...

當name變量的形式為package.module時,通常返回頂級包(名稱直到第一個點),而不是按名稱命名的模塊。 但是,當給出非空的fromlist參數時,將返回以名稱命名的模塊。 這樣做是為了與為不同種類的import語句生成的字節碼兼容。 使用“ import spam.ham.eggs”時,頂級垃圾郵件必須放置在導入名稱空間中,但是當使用“ from spam.ham import eggs”時,必須使用spam.ham子軟件包來查找eggs變量。 。 作為解決此問題的方法,請使用getattr()提取所需的組件。 例如,您可以定義以下助手:

 def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod 

釋義:

當您請求somepackage.somemodule__import__返回somepackage.__init__.py ,通常為空。

如果提供fromlist ,它將返回somemodule (想要的somemodule內的變量名列表,實際上並沒有返回)

您也可以像我一樣使用他們建議的功能。

注意:我問這個問題完全是想自己回答這個問題。 我的代碼中有一個大錯誤,並且由於錯誤診斷,我花了很長時間才弄清楚它,所以我認為我會幫助SO社區並發布遇到的問題。

python 2.7具有importlib,虛線路徑按預期解析

import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()

有一個更簡單的解決方案,如文檔中所述:

如果只想按名稱導入模塊(可能在包中),則可以調用__import __(),然后在sys.modules中進行查找:

>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>

有一些您想要的東西可以工作: twisted.python.reflect.namedAny

>>> from twisted.python.reflect import namedAny
>>> namedAny("operator.eq")
<built-in function eq>
>>> namedAny("pysqlite2.dbapi2.connect")
<built-in function connect>
>>> namedAny("os")
<module 'os' from '/usr/lib/python2.5/os.pyc'>

對於python 2.6,我編寫了以下代碼段:

def import_and_get_mod(str, parent_mod=None):
    """Attempts to import the supplied string as a module.
    Returns the module that was imported."""
    mods = str.split('.')
    child_mod_str = '.'.join(mods[1:])
    if parent_mod is None:
        if len(mods) > 1:
            #First time this function is called; import the module
            #__import__() will only return the top level module
            return import_and_get_mod(child_mod_str, __import__(str))
        else:
            return __import__(str)
    else:
        mod = getattr(parent_mod, mods[0])
        if len(mods) > 1:
            #We're not yet at the intended module; drill down
            return import_and_get_mod(child_mod_str, mod)
        else:
            return mod

我做的方法是

foo = __import__('foo',  globals(), locals(), ["bar"], -1)
foobar = eval("foo.bar")

然后我可以通過訪問任何內容

foobar.functionName()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM