2011-02-18 13 views
0

関連検査を行う、私は自分のコンピュータ上で開いているフォルダを持っている、自動インポート - Pythonランタイム

OpenFunctions\ 
    ____Template.py 
    function1.py 
    function2.py 
    ...... 
    functionx.py 

このフォルダには、アプリケーション全体の能力を拡張するための実験的な目的でありますすることができます。だから、それは迅速かつ乾いた試行であると考えてみましょう。この場合、セキュリティ上の配慮はありません。

私は、____Template.pyに続いてfunctionx.pyをドロップすると、アプリケーションは新しい機能が利用可能であることを知ることができ、この新しい結合ファイルで定義された関数をプラグインシステムのように呼び出すが、ビットが異なる。

私は____inspect.pyを書いたので、アプリケーションは何が入力されたのかを知ることができます。ここで

はここ

____inspect.py 

def get_this_file_defined_functions(name_filter = "__"): 
    import inspect, sys 
    f = inspect.getmembers(sys.modules[__name__], inspect.isfunction) 
    return [x for x in f if not x[0].startswith(name_filter)] 

def get_this_module_sub_modules(name_filter = "__"): 
    import os.path, pkgutil 
    pkgpath = os.path.dirname(__file__) 
    m = [name for _, name, _ in pkgutil.iter_modules([pkgpath])] 
    return [x for x in m if not x[0].startswith(name_filter)] 

def import_sub_modules_under_me(auto_exec_function = "auto_exec"): 
    m = get_this_module_sub_modules() 
    for i in m: # need try except later 
     exec "global %s; import %s" % (i, i) 
     #this will auto invoke __init__.py if sub modules folder is included 
    for i in m: 
     try: 
      eval(i).eval(auto_exec_function)() 
     except AttributeError: 
      print "module %s has no function %s", % (i, auto_exec_function) 
     else: 
      print "error on execute %s in module %s", % (auto_exec_function, i) 

def execute_all_homonymy_functions(exec_function = "exec"): 
    m = get_this_module_sub_modules() 
    for i in m: 
     #I need here for test if the module has been imported 
     eval(i).eval(exec_function)() 

である私もここで

main.py 
____inspect.py 
OpenFunctions\ 
    __init__.py 
    ____Template.py 
    function1.py 
    function2.py 
    ...... 
    functionx.py 
    module_aa 
     \__init__.py 
      aa.py 
      aa1.py 

以下に構造を拡張したい上記の考えに基づいて

____Template.py 

def __you_can_not_see_me(): pass # because filtered by str.startswith() 
def auto_exec(): pass    # this will be auto executed 
def you_can_get_me(): pass 
def you_can_get_me1(): pass 
def you_can_get_me2(): pass 

__init__.pyしばらくmain.pyです見えるかもしれない

import ____inspect 
____inspect.import_sub_modules_under_me() 
____inspect.execute_all_homonymy_functions("what_ever_i_want") 

質問:

  1. __init__上記のコードは動作しないでしょうsys.modules[__name__]____inspect私が欲しい OpenFunctionsまたはmodule_aaを呼び出しますがされていない場合ので、sys.modules[__name__]を渡す回避する方法がありますmain.pyまたは__init__.pyimport_sub_modules_under_me()に?

  2. execute_all_homonymy_functions()は、サブモジュールまたは単一ファイルに存在するにもかかわらず、フォルダ内の同じ名前機能をすべて実行すると思いますが、新しいモジュールが追加された場合はallと最新バージョンを呼び出します。ソースがランタイムに変更されました。次に、コードimport aa, reload(aa)を使用したいと思っていますが、リンクの下に間違っていると思われるかもしれません。 問題は、私は_ _inspect.py I need here for test if the module has been importedをマークし

    [http://stackoverflow.com/questions/5027352/how-to-test-if-one-python-module-has-been-imported]

  3. 私はファイルを呼び出す前にファイル内の関数の戻り値の型を知りたいので、各関数に装飾を付けることを提案しました。だから、私の計画は次のとおりです。

\ nは

____decorate.py 

def attrs(**kwds): 
    def decorate(f): 
     for k in kwds: 
      setattr(f, k, kwds[k]) 
     return f 
    return decorate 

functionx.py 
import ../____decorate.py 

@attrs(argument_types=(int, int,),returns=int) 
def __you_can_not_see_me(): pass 

@attrs(argument_types=(int, int,),returns=int) 
def auto_exec(): pass    # I will be auto executed 

@attrs(argument_types=(int, int,),returns=int) 
def you_can_get_me(): pass 

@attrs(argument_types=(int, int,),returns=int) 
def you_can_get_me1(): pass 

@attrs(argument_types=(int, int,),returns=int) 
def you_can_get_me2(): pass 

は、ケースを点検するために、それがうまく動作ですか?それとももっと良い解決策がありますか?

最後の1:コードの下には

exec "global %s; import %s" % (i, i) 
eval(i).eval(auto_exec_function)() 

は、上記の二つのラインのための任意の代替を醜いですか?

ありがとうございました。

RGS、 KC

答えて

2

は、まず、あなたの最後の質問に対処するには、次の動的importlib.import_module()を使用し、Pythonの最近のバージョンでは、モジュールをインポートするには、それはそれが何のためにあるのかです。古いバージョンのPythonを使用している場合は、代わりに__import__を使用する必要があります(但し、ドキュメント内の直接アプローチの特異性を確認してください - import_module()関数が置き換えられた理由があります)。

最初の質問に答えるには、呼び出し元関数のグローバル環境に関する情報を取得するための公式の移植可能な方法はありません。したがって、最も適切な答えは、いつでも引数として__name__を渡すことです。

リロード中にすべてが正しく動作するわけではないので、Pythonでリロードするのはちょっと危険です(多くの標準ライブラリモジュールでも、それらをリロードすると失敗します)。

私は本当にPythonでのプラグイン・アーキテクチャについては、この既存の質問への回答探検いくつかの時間費やしてお勧め:返信用Building a minimal plugin architecture in Python

+0

おかげで、私は前にサーバルプラグインモジュールを読んだが、私は私のための一つの共通の問題を発見したものですプラグインシステムではクラスが好きかもしれません - 厳密なテンプレートに続いてプラグインを定義する必要があります。ほとんどのシステムでは大丈夫ですが、私がそれらの汚い作品を完成させるためには、特別な設計コードを書く価値がありません。もう一度あなたの提案に感謝します – user478514

+0

と汚れているだけで私の英語のために残念、ここで一度を意味します。 – user478514

関連する問題