web-dev-qa-db-ja.com

Pythonで__import __( 'module_name')をアンチパターンとして使用していますか?

私は現在、Python 2プロジェクトをリファクタリングしています。これには、特定のAPIを実装するPythonモジュールであるプラグインを追加または削除する機能が含まれています。

メインアプリは、プラグインの追加/削除/更新フックにアクセスします。データベースからプラグイン名を取得した後の__import__('plugin_name').hook_add()ですが、これはハッキーなアプローチのようです。そうは言っても、プログラムでプラグインにアクセスするためのより良い方法はわかりません。

これはPythonのアンチパターンと見なされますか?

1
Jules

Pythonで__import__('module_name')をアンチパターンとして使用していますか?

___import___のAPIはやや誤解を招く可能性があります。私は個人的に可能な限りそれを避けたいと思います。

docs for Python 3状態:

__import__()を直接使用することもお勧めしません。これにより、importlib.import_module()が優先されます。

___import___のAPIは次のとおりです。

_mod = __import__(
    module, # string of dotted name
    globals=None, # only needed to do relative import
    locals=None, # implementation ignores this
    fromlist=()) # fromlist just needs to be non-empty... :(
    level=0 # relative import, not going into this part
    )
_

Fromlistが空の場合は、モジュールをインポートしますが、次のようにルートパッケージが返されるため、ドットでルックアップして元に戻す必要があります。

_>>> foo = __import__('foo.bar.baz')
>>> foo.bar.baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>
_

これはと同じです

_>>> import foo.bar.baz
>>> foo.bar.baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>
_

モジュールが必要な場合は、fromlistを空にしないでください。

_>>> baz = __import__('foo.bar.baz', fromlist=[None])
>>> baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>
_

これはと同じです

_>>> from foo.bar import baz
>>> baz
<module 'foo.bar.baz' from /.../foo/bar/baz.py>

>>> baz is foo.bar.baz
True
_

代わりに_importlib.import_module_を使用してください:

import_module の使用方法は次のとおりです。

_>>> from importlib import import_module
>>> baz = import_module('foo.bar.baz')
_

それはずっといいです。

3
Aaron Hall