3

Parallel Python モジュール ( pp) を使用しており、ワーカーにジョブを送信したいと考えています。しかし、実行したい関数は別のモジュール (Cython で作成) にあり、関数名を新しいワーカーにインポートする方法がわかりません。ここで提案されている方法、つまり関数内にモジュール「walkerc」をインポートすることはできません。これは、walk 自体が walkerc でファイル名「walkerc.so」から定義されているためです。

import pp
from walkerc import walk
# Other stuff here
ser = pp.Server()
# Some more definitions
ser.submit(walk, (it, params))
ser.submit(walk, (1000, params), modules = ("walkerc",), globals = globals())

上記のステートメントは両方とも失敗し、次のエラーが発生します。

トレースバック (最新の呼び出しが最後):

ファイル ""、1 行目、ser.submit(walk, (1000, params)、modules = ("walkerc",)、globals = globals()) 内

ファイル "/usr/lib/python2.7/site-packages/pp.py"、458 行目、送信 sfunc = self.__dumpsfunc((func, ) + depfuncs, modules)

ファイル "/usr/lib/python2.7/site-packages/pp.py"、629 行目、__dumpsfunc のソース = [self.__get_source(func) for func in func]

ファイル "/usr/lib/python2.7/site-packages/pp.py"、696 行目、__get_source sourcelines = inspect.getsourcelines(func)[0] 内

ファイル "/usr/lib/python2.7/inspect.py"、690 行目、getsourcelines 行、lnum = findsource(object)

ファイル「/usr/lib/python2.7/inspect.py」、526行目、findsource file = getfile(object)

ファイル "/usr/lib/python2.7/inspect.py"、420 ​​行目、getfile の '関数、トレースバック、フレーム、またはコード オブジェクト'.format(object))

TypeError: '<'組み込み関数 walk'>' は、モジュール、クラス、メソッド、関数、トレースバック、フレーム、またはコード オブジェクトではありません

関数 'walk' 自体はメイン プログラム内で適切にインポートされますが、問題があるのはそれを新しいワーカーに送信するプロセスです。

関数名「walk」を正しく指定するにはどうすればよいですか? Cython で変更してパフォーマンスを向上させたいので、呼び出したのと同じファイルで 'walk' を定義したくありません。代替手段はありますか?

4

1 に答える 1

2

たとえばwalk、関数の名前を別の名前に変更してみてください。mywalk例外テキストが示唆するように、あなたの環境には という名前の組み込み関数があるwalkようで、inspectモジュールが混乱します。

私は自分のシステムでこのようにインポートしたwalk関数を正常に渡すことができます。ここで競合はなく、それ以上必要なものはありません。関数は指定された引数を使用して実行されます。

import pp
from walkerc import walk

pps = pp.Server()
pps.submit(walk, args=(1,))

しかしdir、確かに組み込み関数であるを渡します。

pps.submit(dir)

あなたとまったく同じエラーが発生します:

トレースバック (最新の呼び出しが最後):
  ファイル「parallel.py」の 9 行目
    pps.submit(ディレクトリ)
  ...
  ファイル ".../lib/python2.7/inspect.py"、420 ​​行目、getfile 内
    '関数、トレースバック、フレーム、またはコード オブジェクト'.format(object))
TypeError: モジュール、クラス、メソッド、関数、トレースバック、フレーム、またはコード オブジェクトではありません

以下の議論の後に更新します。

ここでの問題は、Python がC 拡張からのメンバーを組み込みとして扱うことです。上記のコードは通常の Python モジュールで動作しますが、C 拡張機能から関数をインポートして渡すときに OP のエラーを再現できました。

そのため、C 拡張関数の呼び出しを通常の Python 関数内にラップしました。これでうまくいきます。walk関数のインポートがラッピング関数に移動されたため、ディスパッチ時に独自のコンテキスト自体を構築できることに注意してください。

import pp

def walk(n):
    import walkerc
    return walkerc.walk(n)

def print_callback(result):
    print('callback: ', result)

pps = pp.Server()
job = pps.submit(walk, args=(1,), callback=print_callback)
于 2014-06-24T11:08:48.200 に答える