5

プログラム (計算生物学の実験) でオプションを渡すときは、通常、.py ファイルを介して渡します。
したがって、次のような.pyファイルがあります。

starting_length=9
starting_cell_size=1000
LengthofExperiments=5000000

次に、ファイルを実行してデータを取得します。プログラムはすべて私のマシン上にあり、他の誰もアクセスできないため、簡単な方法で安全です。
同様のファイルを非常に簡単に作成することもできます。

def writeoptions(directory):
    options=""
    options+="starting_length=%s%s"%(starting_length,os.linesep)
    options+="starting_cell_size=%s%s"%(starting_cell_size,os.linesep)
    options+="LengthofExperiments=%s%s"%(LengthofExperiments,os.linesep)
...
    open("%s%soptions.py"%(directory,os.sep),'w').write(options)

パラメータの1つとして関数を渡したい:

starting_length=9
starting_cell_size=1000
LengthofExperiments=5000000

def pippo(a,b):
    return a+b
functionoperator=pippo

そしてもちろん、実際の実験では、関数 pippo はもっと複雑になります。そして、実験ごとに異なります。

しかし、私ができないのは、関数を自動的に書くことです。要するに、オプションの1つが関数である場合、オプションを書き続けるために writeoptions 関数を一般化する方法がわかりません。もちろん、元のファイルをコピーすることもできますが、これは洗練されておらず、非効率的であり (使用されていない余分なオプションが多数含まれているため)、通常は問題を解決できません。

Python が変数の値を書き留めるように、どのようにして関数のコードを書き留めますか?

4

5 に答える 5

15
vinko@mithril$ もっと見る

デフ foo(a):
  印刷する

vinko@mithril$ もっと見る b.py

インポート
輸入検査

a.foo(89)
print inspect.getsource(a.foo)

vinko@mithril$ python b.py
89
デフ foo(a):
  印刷する

于 2008-12-30T11:18:39.257 に答える
2

また、データを永続化する他の方法を検討することもできます。私自身 (天文学) の研究では、再現性を確保するためにスクリプトを保存する 2 つの異なる方法を試してきました。1 つ目は、それらを Subversion リポジトリ内に排他的に配置し、ジョブ送信スクリプトに自動的にコミットさせることです。たとえば、これを bash で実行したいだけの場合:

alias run_py='svn ci -m "Commit before running"; python2.5 $*'

スクリプト内で、そのファイルの現在のサブバージョンのリビジョン番号を前に付けて出力すると、実行された各スクリプトと入力の記録が得られます。必要に応じて、これを Subversion から引き戻すことができます。

関数への入力を追跡するもう 1 つの方法は、十分な機能はありませんが、XML-RPC 入力を受け入れ、Python バインディングが付属している Pastebin であるLodgeItのようなものを使用できます。(ローカルにインストールでき、既存の貼り付けへの返信と更新をサポートしています。)

ただし、比較的少量のコードを含めることを探している場合は、inspect を使用した Vinko のソリューションが非常にうまく機能するはずです。Doug Hellmanは、彼のPython Module of the Weekシリーズでこのモジュールを取り上げました。inspect各オプションと引数を調べて、必要に応じて出力するデコレータを作成できます (引数の名前を取得するために使用します)。inspect.getargspec

import inspect
from functools import wraps

def option_printer(func):
    @wraps(func)
    def run_func(*args, **kwargs):
        for name, arg in zip(inspect.getargspec(func)[0], args) \
                       + sorted(kwargs.items()):
            if isinstance(arg, types.FunctionType): 
                print "Function argument '%s' named '%s':\n" % (name, func.func_name)
                print inspect.getsource(func)
            else:
                print "%s: %s" % (name, arg)
        return func(*args, **kwargs)
    return run_func

これはおそらくもう少し洗練されたものにすることができますが、私のテストでは、引数と変数の単純なセットに対して機能します。さらに、ラムダで問題が発生する可能性があります。

于 2008-12-30T14:12:54.320 に答える
0

これについて質問していますか?

def writeoptions(directory):
    options=""
    options+="starting_length=%s%s"%(starting_length,os.linesep)
    options+="starting_cell_size=%s%s"%(starting_cell_size,os.linesep)
    options+="LengthofExperiments=%s%s"%(LengthofExperiments,os.linesep)
    options+="def pippo(a,b):%s" % ( os.linesep, )
    options+="    '''Some version of pippo'''%s" % ( os.linesep, )
    options+="    return 2*a+b%s" % ( os.linesep, )
    open("%s%soptions.py"%(directory,os.sep),'w').write(options)

または、他の何か?

于 2008-12-30T11:21:05.697 に答える
0

あなたが求めることは可能ですが (Vinko が示したように)、code を共有する方がクリーンだと思います。pippo両方のプログラムがアクセスできるサブモジュールに入れます。

于 2008-12-30T11:24:44.237 に答える
0

逆アセンブラとバイトコード (たとえばinspect )の話題に飛び込む代わりに、生成された Python ソースをモジュール ( file.py ) に保存し、後でそれをインポートしてみませんか?

optionsと呼ばれるものを処理する、より標準的な方法を検討することをお勧めします。たとえば、JSONモジュールを使用して、データを保存または復元できます。または、marshalおよびpickleモジュールを調べてください。

于 2008-12-30T11:25:27.793 に答える