__import__
を点線の名前で使用する場合:somepackage.somemodule
、返されるモジュールはsomemodule
ではなく、返されるものはほとんど空のようです。何が起きてる?
__import__
のpythonドキュメントから:
__import__( name[, globals[, locals[, fromlist[, level]]]])
.。
Name変数がpackage.moduleの形式の場合、通常、名前で名前が付けられたモジュールではなく、最上位のパッケージ(最初のドットまでの名前)が返されます。ただし、空でないfromlist引数を指定すると、名前で指定されたモジュールが返されます。これは、さまざまな種類のインポートステートメント用に生成されたバイトコードとの互換性のために行われます。 「importspam.ham.eggs」を使用する場合は、最上位パッケージのスパムをインポートする名前名に配置する必要がありますが、「from spam.ham importeggs」を使用する場合は、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
を返しますが、これは多くの場合空です。
somemodule
(実際には返されないfromlist
内の変数名のリスト)を指定すると、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()