3

私は、遺伝子技術を使用して方程式を進化させるプログラムを書いています。関数「mainfunc」をParallelPythonの「submit」関数に送信できるようにしたい。関数'mainfunc'は、Utilityクラスで定義された2つまたは3つのメソッドを呼び出します。他のクラスをインスタンス化し、さまざまなメソッドを呼び出します。私が欲しいのは、すべてを1つの名前空間に収めることだと思います。そのため、関数'mainfunc'内のクラスの一部(おそらくすべてである必要があります)をインスタンス化しました。ユーティリティメソッド'generate()'を呼び出します。一連の実行に従うとすると、コード内のすべてのクラスとメソッドが関係します。

これで、方程式がツリーに保存されます。ツリーが生成、変更、またはクロスブリードされるたびに、ツリーのディクショナリ属性からアクセスできるように、ノードに新しいキーを指定する必要があります。クラス'KeySeq'はこれらのキーを生成します。

Parallel Pythonでは、「mainfunc」の複数のインスタンスをPPの「submit」関数に送信します。それぞれが「KeySeq」にアクセスできる必要があります。それらがすべてKeySeqの同じインスタンスにアクセスして、返されたツリーのどのノードも同じキーを持たないようにすると便利ですが、必要に応じてそれを回避できます。

だから:私の質問は、すべてをmainfuncに詰め込むことについてです。ありがとう(編集)mainfuncにすべてを含めない場合は、さまざまな場所でさまざまな議論を渡すことによって、依存関数などについてPPに伝えようとする必要があります。私はそれを避けようとしています。

(後期編集)ks.next()が'generate()関数内で呼び出された場合、エラー' NameError:global name'ks' isnotdefined'を返します。

class KeySeq:
    "Iterator to produce sequential \
    integers for keys in dict"
    def __init__(self, data = 0):
        self.data = data
    def __iter__(self):
        return self
    def next(self):
        self.data = self.data + 1
        return self.data
class One:
    'some code'
class Two:
    'some code'
class Three:
    'some code'
class Utilities:
    def generate(x):
        '___________'
    def obfiscate(y):
        '___________'
    def ruminate(z):
        '__________'


def mainfunc(z):
    ks = KeySeq()
    one = One()
    two = Two()
    three = Three()
    utilities = Utilities()
    list_of_interest = utilities.generate(5)
    return list_of_interest

result = mainfunc(params)
4

3 に答える 3

3

プログラムをそのように構成するのは問題ありません。多くのコマンドラインユーティリティは同じパターンに従います。

#imports, utilities, other functions

def main(arg):
    #...

if __name__ == '__main__':
    import sys
    main(sys.argv[1])

このようにして、main関数をインポートして別のモジュールから呼び出すか、コマンドラインから実行することができます。

于 2009-10-13T16:34:00.023 に答える
1

のすべてのインスタンスでmainfunc同じKeySeqオブジェクトを使用する場合は、デフォルトのパラメータ値のトリックを使用できます。

def mainfunc(ks=KeySeq()):
   key = ks.next()

の値を実際に渡さない限り、ksへのすべての呼び出しは、関数が定義されたときに作成されたmainfuncインスタンスを使用します。KeySeq

わからない場合は、次の理由があります。関数はオブジェクトです。属性があります。その属性の1つはfunc_defaults;という名前です。これは、デフォルトを持つシグネチャ内のすべての引数のデフォルト値を含むタプルです。関数を呼び出し、デフォルトの引数に値を指定しない場合、関数はから値を取得しますfunc_defaults。したがってmainfunc、の値を指定せずに呼び出すと、タプルからインスタンスksが取得されます。これは、のそのインスタンスでは、常に同じインスタンスです。KeySeq()func_defaultsmainfuncKeySeq

ここで、 「PPmainfuncの関数にの複数のインスタンス」を送信するとします。submit本当に複数のインスタンスを意味しますか?もしそうなら、私が説明しているメカニズムは機能しません。

ただし、関数の複数のインスタンスを作成するのは難しいです(そして、投稿したコードは作成しません)。たとえば、この関数は、g呼び出されるたびに新しいインスタンスを返します。

>>> def f():
        def g(x=[]):
            return x
        return g
>>> g1 = f()
>>> g2 = f()
>>> g1().append('a')
>>> g2().append('b')
>>> g1()
['a']
>>> g2()
['b']

引数なしで呼び出すと、タプルg()からデフォルト値(最初は空のリスト)が返されます。とは関数の異なるインスタンスであるfunc_defaultsため、引数のデフォルト値異なるインスタンスです。これは上記のとおりです。g1g2gx

デフォルト値のトリッキーな副作用を使用するよりもこれをより明確にしたい場合は、別の方法があります。

def mainfunc():hasattr(mainfunc、 "ks")でない場合:setattr(mainfunc、 "ks"、KeySeq())key = mainfunc.ks.next()

最後に、投稿したコードが見落としている非常に重要な点です。共有データに対して並列処理を行う場合、そのデータにアクセスするコードはロックを実装する必要があります。Parallel Pythonドキュメントの例を見て、クラスでcallback.pyロックがどのように使用されているか、およびその理由を確認してください。Sum

于 2009-10-14T00:26:26.007 に答える
0

Pythonでのクラスの概念は適切ではないと思います。おそらく、基本を確認することをお勧めします。このリンクが役立ちます。

Pythonの基本-クラス

于 2009-10-16T10:01:41.460 に答える