質問

__ import __ をドット付きの名前( somepackage.somemodule など)で使用すると、返されるモジュールは somemodule ではなく、返されるものは何でもほとんど空のようです!ここで何が起こっているのですか?

役に立ちましたか?

解決

__ import __ のPythonドキュメントから:

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

...

     

名前変数が次の形式の場合   package.module、通常、   トップレベルパッケージ(名前まで   ではなく、最初のドット)が返されます   名前で指定されたモジュール。ただし、   空でないfromlist引数が指定されている、   名前で指定されたモジュールが返されます。   これはとの互換性のために行われます   のために生成されたバイトコード   さまざまな種類のimportステートメント。   " import spam.ham.eggs"を使用する場合、   トップレベルのパッケージスパムを配置する必要があります   インポートする名前空間で、ただし   「spam.ham import eggsから」を使用して、   spam.hamサブパッケージを使用して、   卵の変数を見つけます。として   この動作の回避策、使用   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帰属
所属していません StackOverflow
scroll top