1

現在、モジュール クラスの拡張をサポートするために、ある種の小さな API を作成しています。ユーザーは自分のクラス名を構成に書き込むだけで、プログラムで使用できるようになります。create(**kwargs)クラスのモジュールには、基本モジュール クラスのインスタンスを返すために呼び出される関数があり、特別なフォルダーに配置されるという契約があります。ただし、インポートが動的に行われるとすぐに isinstance チェックが失敗します。

モジュールは lib/services/ nameに配置されます

モジュール基本クラス (lib/services/service 内)

class Service:
    def __init__(self, **kwargs):
        #some initialization

サンプル モジュール クラス (lib/services/ping 内)

class PingService(Service):
    def __init__(self, **kwargs):
        Service.__init__(self,**kwargs)
        # uninteresting init

def create(kwargs):
    return PingService(**kwargs)

インポート機能

import sys
from lib.services.service import Service

def doimport( clazz, modPart, kw, class_check):
    path = "lib/" + modPart
    sys.path.append(path)
    mod = __import__(clazz)
    item = mod.create(kw)

    if class_check(item):
        print "im happy"
        return item

呼び出しコード

class_check = lambda service: isinstance(service, Service)
s = doimport("ping", "services", {},class_check)

print s

from lib.services.ping import create

pingService = create({})
if isinstance(pingService, Service):
    print "why this?"

私は一体何を間違っているのですか

これは圧縮された小さな例です。test.py引数なし で抽出して実行するだけです。

4

1 に答える 1

2

問題はping.pyファイルにありました。正確な理由はわかりませんが、動的にインポートすると行が受け入れられなかったfrom service import Serviceので、相対パスに変更するだけです: from lib.services.service import Service。に追加lib/servicesするとsys.path、継承を機能させることができませんでした。これは奇妙でした...

また、imp.load_sourceより堅牢に見えるものを使用しています:

import os, imp
def doimport( clazz, modPart, kw, class_check):
    path = os.path.join('lib', modPart, clazz + '.py')
    mod = imp.load_source( clazz, path )
    item = mod.create(kw)

    if class_check(item):
        print "im happy"
        return item
于 2013-06-18T21:51:28.570 に答える