2

関数を使用して、ファイルパスを使用してモジュールをインポートするプログラムを作成していますimp.load_source(module_name,module_path)。このモジュールからオブジェクトをに渡そうとすると、問題が発生するようですProcess

例:

import multiprocessing
import imp

class MyProcess(multiprocessing.Process):
    def __init__(self,thing):
        multiprocessing.Process.__init__(self)
        self.thing=thing
    def run(self):
        x=self.thing


if __name__=="__main__":
    module=imp.load_source('life', 'C:\\Documents and Settings\\User\\workspace\\GarlicSim\\src\\simulations\\life\\life.py')
    thing=module.step
    print(thing)
    p=MyProcess(thing)
    p.start()

注:このコードを「機能」させるには、指定したパラメーターを別のimp.load_sourceものに置き換える必要があります。コンピューター上のPythonファイルである必要があり、できれば同じフォルダーにない必要があります。次に、でthing=module.step、ステップの代わりに、そのファイルで定義されているランダムな関数またはクラスを入力し.pyます。

次のトレースバックを取得しています。

<function step at 0x00D5B030>
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python26\lib\multiprocessing\forking.py", line 342, in main
    self = load(from_parent)
  File "C:\Python26\lib\pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "C:\Python26\lib\pickle.py", line 858, in load
    dispatch[key](self)
  File "C:\Python26\lib\pickle.py", line 1090, in load_global
    klass = self.find_class(module, name)
  File "C:\Python26\lib\pickle.py", line 1124, in find_class
    __import__(module)
ImportError: No module named life

だから私は何をしますか?

編集:

WinXPでPython2.6.2c1を使用しています。

4

3 に答える 3

-1

test.py任意のフォルダ:

import multiprocessing
import imp

class MyProcess(multiprocessing.Process):
    def __init__(self,thing):
        multiprocessing.Process.__init__(self)
        self.thing=thing
    def run(self):
        print 'running...', self.thing()


if __name__=="__main__":
    module=imp.load_source('life', '/tmp/life.py')
    thing=module.step
    print(thing)
    p=MyProcess(thing)
    p.start()

life.pyオン/tmp:

def step():
    return 'It works!'

実行中test.py:

$ python test.py
<function step at 0xb7dc4d4c>
running... It works!

テストしたところ動作するので、何か間違ったことをしているに違いありません。質問を編集して、機能していない実際のコードを貼り付けてください。

デフォルトのpython(Python 2.6.2 release26-maint、2009年4月19日、01:56:41)でubuntu Jaunty 9.04を使用しています。テストできるウィンドウがないため、問題がウィンドウのみかどうかはわかりません。

これが、インポート パスのマングリングが悪い考えである理由です。すべてのプラットフォーム/環境で正しく動作することは決してなく、ユーザーはおそらく怒るでしょう。モジュールをpythonモジュール検索パスに配置することにより、モジュールを見つけるpythonの方法を使用することをお勧めします。それはどこでも一貫して機能します。

于 2009-05-06T11:59:20.607 に答える
-1

XPでPython 2.5を実行して、次のことを行いました...

D:\Experiments\ModuleLoading\test.py

import imp

if __name__=="__main__":
    module=imp.load_source('life', r'D:\Experiments\ModuleLoading\somefolder\life.py')
    thing=module.step
    print(thing)

D:\Experiments\ModuleLoading\somefolder\step.py

def step():
    return 'It works!'

...そしてスクリプトを実行すると、次のようになります。

D:\jcage\Projects\Experiments\ModuleLoading>test.py
<function step at 0x00A0B470>

...最初にそれを試して、モジュールがマルチプロセッシングなしでロードできることを確認してください。

[編集]わかりました。フォークされたプロセスにインポートするのは間違いなく問題です。ドキュメントには、 windows に固有のビットとピースがいくつかあります。

より酸洗いしやすい

Process.__init__() へのすべての引数が pickleable であることを確認してください。これは特に、バインドされたメソッドまたはバインドされていないメソッドを Windows のターゲット引数として直接使用できないことを意味します。関数を定義して代わりに使用してください。また、Process をサブクラス化する場合は、Process.start() メソッドが呼び出されたときにインスタンスが pickle 化可能であることを確認してください。

グローバル変数

子プロセスで実行されるコードがグローバル変数にアクセスしようとした場合、表示される値 (存在する場合) は、 Process.start() が呼び出された時点の親プロセスの値と同じではない可能性があることに注意してください。 . ただし、モジュール レベルの定数にすぎないグローバル変数は問題ありません。

メインモジュールの安全なインポート

意図しない副作用 (新しいプロセスの開始など) を引き起こすことなく、メイン モジュールが新しい Python インタープリターによって安全にインポートできることを確認してください。

[編集 2]途中でインポートできない理由はありますか? 問題は、新しいプロセスを起動すると、同じアドレス空間で実行されていないため、元のスレッドの関数にアクセスしようとしても機能しないことだと思います。

代わりにこれを行うことができますD:\Experiments\ModuleLoading\test.py

from multiprocessing import Process
import imp

class MyProcess(Process):
    def __init__(self):
        Process.__init__(self)

    def run(self):
        print 'run called...'
        module=imp.load_source('life', r'D:\Experiments\ModuleLoading\somefolder\life.py')
        print 'running...', module.step()

if __name__=="__main__":
    p=MyProcess()
    p.start()
于 2009-05-06T12:50:49.280 に答える