0

Python3で書いています。

プログラムにプラグインのサポートを追加したいと考えています。重いフレームワークは使いたくないので、最小限のものを自分で書くことにしました。

ちなみに、プラグインは時間までに実行する必要があります。再実行時にプラグインを常にアンロードしてロードするとは限りません。プラグインはすべてのデータを失います。

私のフォルダ構造はここにあります:

interfaces/
├── dummy
├── gmail
│   ├── __init__.py
│   └── __pycache__
│       └── __init__.cpython-33.pyc
└── hello
    ├── __init__.py
    └── __pycache__
        └── __init__.cpython-33.pyc

次に、プラグインをロードして実行するためのコードを書きました。

#!/usr/bin/python3
import os
import imp

INTERFACES_FOLDER = './interfaces'
MAIN_MODULE = '__init__'

def search_plugins():
    plugins = []
    plugins_folders = os.listdir(INTERFACES_FOLDER)

    for i in plugins_folders:
        plugin_folder = os.path.join(INTERFACES_FOLDER, i)

        if not os.path.isdir(plugin_folder):
            continue
        if not MAIN_MODULE + '.py' in os.listdir(plugin_folder):
            continue

        info = imp.find_module(MAIN_MODULE, [plugin_folder])
        plugins.append({'name': i, 'info': info})
    return plugins


def load_plugin(plugin):
    return imp.load_module(MAIN_MODULE, *plugin["info"])


plugins_list = search_plugins()
plugins = []

for i in plugins_list:
    module = load_plugin(i)
    print(module)
    plugins.append(module)

print(plugins)

出力:

# it works!
<module '__init__' from './interfaces/gmail/__init__.py'>
<module '__init__' from './interfaces/hello/__init__.py'>

# what's wrong?
[<module '__init__' from './interfaces/hello/__init__.py'>, 
 <module '__init__' from './interfaces/hello/__init__.py'>]

ご覧のとおり、プラグインをロードすると、すべてが正しく機能しています。しかし、それらをリストに追加すると、異なるモジュールが同じモジュールになります。

どうしたの?

4

1 に答える 1

1

異なるモジュールをインポートしますが、名前は同じです (それらはすべて「init」と呼ばれます)。Python は、2 番目のモジュールをインポートすると、「init」というモジュールが既にインポートされていることに気づき、それを返します。

インポートするモジュールは、"gmail" および "hello" モジュールです。それはうまくいくかもしれません。

ただし、独自のプラグイン システムを作成することについて再考することをお勧めします。それは本当に簡単ではありません。簡単に検索すると、いくつかのプラグイン システムが見つかります。軽量なものもあれば、それほど多くないものもあります。ほとんどが放棄されています。これは、これが思ったほど簡単ではないことを示しています。

おそらく最も広く使用されている Python のプラグイン システムは、最も柔軟性が高く、最も古いものの 1 つであるZope Component Architectureです。ドキュメントも参照してください。Python 3 では、クラス本体ステートメントの代わりにクラス デコレータを使用することに注意してください。

もう 1 つの一般的なプラグイン システムは、Distributeの「エントリ ポイント」です。これでプラグインをロードまたはアンロードできるかどうかはわかりませんが、これは非常に軽量です。

私が見たことのない他のものはYapsyで、放棄されたように見える「Plugins」と呼ばれるもの、「PyPlugin」と呼ばれるものも放棄され、「easy_plugins」と呼ばれるものは非常に新しく、まだ放棄されていないようです。

プラグイン マネージャーのコード例を次に示します。

于 2012-12-05T11:12:33.127 に答える