2009-05-06 12 views
2

Ich schreibe ein Programm, das ein Modul mit einem Dateipfad importiert, mit der Funktion . Es scheint ein Problem zu verursachen, wenn ich versuche, Objekte von diesem Modul in eine Process zu übergeben.Verwenden von Python-Multiprocessing beim Importieren eines Moduls über Dateipfad

Ein Beispiel:

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() 

Hinweis: für diesen Code „Arbeit“, die Parameter ersetzen muss ich mit etwas imp.load_source gab anderes: Es hat einige Python-Datei auf Ihrem Computer, vorzugsweise nicht im selben Ordner. Dann, in thing=module.step, anstelle von Schritt in eine zufällige Funktion oder Klasse, die in dieser .py Datei definiert ist.

ich folgende Zurückverfolgungs bin immer:

<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 

Also, was soll ich tun?

EDIT:

Ich verwende Python 2.6.2c1 auf Win XP.

Antwort

-1

test.py auf einen beliebigen Ordner:

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 auf /tmp:

def step(): 
    return 'It works!' 

test.py Laufen:

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

ich gerade getestet und es funktioniert, so dass Sie etwas tun müssen sonst falsch. Bitte bearbeiten Sie Ihre Frage und fügen Sie den echten Code ein, der nicht funktioniert.

Ich benutze Ubuntu Jaunty 9.04 mit Standard-Python (Python 2.6.2 Release26-Maint, 19. April 2009, 01:56:41). Ich weiß nicht, ob dein Problem Windows-Only ist, weil ich keine Windows zum Testen habe.

Das ist ein Grund, dass Mangeln mit Importpfaden ist eine schlechte Idee. Sie werden es nie für alle Plattformen/Umgebungen schaffen, und Ihre Benutzer werden wahrscheinlich wütend werden. Verwenden Sie besser die Python-Methode, um Module zu finden, indem Sie das Modul auf den Python-Modul-Suchpfad setzen. Das würde überall konsistent funktionieren.

+0

ich Ihren Code kopiert, nur ' '/ tmp/life.py'' auf'' tmp \\ life.py'' ändern, (ich bin auf Windows XP.) erhalte ich eine Zurückverfolgungs was ich denke, ist das gleiche wie das in meiner Frage, mit diesem "Gurke" -Modul am Ende. Vielleicht passiert es nur unter Windows? (Hinweis: Ich benutze Python 2.6.2c1) –

+0

Verwenden von Ubuntu Jaunty 9.04 mit Standard-Python (Python 2.6.2 Release26-Maint, 19. April 2009, 01:56:41). Ich weiß nicht, ob es nur Windows gibt, ich habe keine Windows zum Testen. Beachten Sie, dass Sie die Schrägstriche/tmp/life.py auch für Windows verwenden können, ohne dass dies in umgekehrte Schrägstriche geändert werden muss. – nosklo

-1

ich folgendes gerade getan haben, auf XP mit Python läuft 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!' 

... und das Skript ausführen gibt:

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

... also zuerst versuchen und sicherstellen, dass das Modul ohne Multiprocessing geladen werden kann?

[Bearbeiten] Okay, es ist definitiv ein Problem beim Import in den Gabelungsprozess. Es gibt some bits and pieces in the documentation which are specific to windows:

Mehr picklability

Stellen Sie sicher, dass alle Argumente zu verarbeiten .__ init __() sind picklable. Dies bedeutet insbesondere, dass gebundene oder nicht gebundene Methoden nicht direkt als Zielargument unter Windows verwendet werden können - definieren Sie einfach eine Funktion und verwenden Sie diese stattdessen. Wenn Sie Prozess ableiten, stellen Sie außerdem sicher, dass die Instanzen bei Aufruf der Process.start() -Methode auswählbar sind.

Globale Variablen

Beachten Sie, dass, wenn Code läuft in einem untergeordneten Prozess eine globale Variable zuzugreifen versucht, dann wird der Wert es (falls vorhanden) sieht vielleicht nicht die gleiche wie der Wert in der Mutter sein Prozess zu dem Zeitpunkt, als Process.start() aufgerufen wurde. Globale Variablen, die nur Modul-Level-Konstanten sind, verursachen jedoch keine Probleme.

Sicher Import von Hauptmodul

Stellen Sie sicher, dass das Hauptmodul kann sicher durch einen neuen Python-Interpreter importiert werden, ohne dass unerwünschte Nebeneffekte (wie ein einen neuen Prozess starten).

[Edit2] Gibt es einen Grund, warum Sie nicht den Import in den Prozess machen kann? Ich denke, das Problem ist, dass wenn Sie den neuen Prozess starten, es nicht im selben Adressraum läuft, so dass der Versuch, auf Funktionen im ursprünglichen Thread zuzugreifen, nicht funktioniert.

Sie können dies tun, für D:\Experiments\ModuleLoading\test.py statt:

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() 
+1

der Backslash ist erforderlich, aber in Ihrem Fall haben Sie keine Escapes. "D: \ foo \ bar \ quux \ life.py" wird zu D: ooar \ quux \ life.py. verwenden Sie stattdessen r'D: \ foo \ bar \ quux \ life.py ', was korrekt zu D: \ foo \ bar \ quux \ life.py – SingleNegationElimination

+0

Guter Punkt - ich werde eine Korrektur machen :-) –

+0

I' Ich bekomme den gleichen Fehler, ob ich \ oder \ oder \ benutze. Und offensichtlich wird das Modul in den Hauptprozess geladen: Andernfalls würde 'print (thing)' fehlschlagen. –

1

Wahrscheinlich ist es nicht wegen der Platzierung von Import-Code in Hauptblock zu arbeiten. Der folgende Code funktioniert unter Windows XP, Python 2.6. Dann wird das Lebensmodul auch in den neuen Prozess importiert.

import multiprocessing 
import imp 

class MyProcess(multiprocessing.Process): 
    def __init__(self,thing): 
    multiprocessing.Process.__init__(self) 
    self.thing=thing 
    def run(self): 
    print("Exiting self.thing") 
    self.thing() 
    print("Finished") 

life=imp.load_source('life', r'd:\temp5\life.py') 

if __name__=="__main__": 
    p=MyProcess(life.step) 
    p.start() 
Verwandte Themen