web-dev-qa-db-de.com

eine weitere Verwirrung mit Multiprocessing-Fehler, 'Modul'-Objekt hat kein Attribut' f '

Ich weiß, dass dies schon vorher beantwortet wurde, aber es scheint, dass die direkte Ausführung des Skripts "python filename.py" nicht funktioniert. Ich habe Python 2.6.2 unter SuSE Linux.

Code:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from multiprocessing import Pool
p = Pool(1)
def f(x):
    return x*x
p.map(f, [1, 2, 3])

Befehlszeile:

> python example.py
Process PoolWorker-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/multiprocessing/process.py", line 231, in _bootstrap
    self.run()
File "/usr/lib/python2.6/multiprocessing/process.py", line 88, in run
    self._target(*self._args, **self._kwargs)
File "/usr/lib/python2.6/multiprocessing/pool.py", line 57, in worker
    task = get()
File "/usr/lib/python2.6/multiprocessing/queues.py", line 339, in get
    return recv()
AttributeError: 'module' object has no attribute 'f'
58
gatoatigrado

Strukturieren Sie Ihren Code so um, dass die Funktion f() definiert wird, bevor Sie eine Instanz des Pools erstellen. Ansonsten kann der Arbeiter Ihre Funktion nicht sehen.

#!/usr/bin/python
# -*- coding: utf-8 -*-

from multiprocessing import Pool

def f(x):
    return x*x

p = Pool(1)
p.map(f, [1, 2, 3])
114
Bartosz

Dieser funktioniert:

#!/usr/bin/python
# -*- coding: utf-8 -*-
from multiprocessing import Pool

def f(x):
    return x*x

if __== "__main__":
    p = Pool(1)
    p.map(f, [1, 2, 3])

Ich bin nicht zu 100% sicher, warum Ihr Code nicht funktioniert, aber ich vermute, der Grund dafür ist, dass untergeordnete Prozesse, die vom Modul multiprocessing gestartet wurden, versuchen, das Hauptmodul zu importieren (um Zugriff auf die von Ihnen definierten Methoden zu erhalten), und Die Zeilengruppe if __== "__main__" ist erforderlich, um den Initialisierungscode nicht auszuführen, in dem Sie Ihren Pool eingerichtet haben.

5
Tamás

Eine Möglichkeit ist, dass Ihre Python-Datei denselben Namen wie ein Modul hat:

  • test.py
  • prüfung/
    • __init__.py

in pickle.py haben Sie den folgenden Fehler:

    def find_class(self, module, name):
      # Subclasses may override this
      __import__(module)
      mod = sys.modules[module] # <- here mod will reference your test/__init__.py
      klass = getattr(mod, name)
      return klass
1
user1143523

Dies kommt von der Tatsache, dass der Hauptprozess mit p = Pool(1) Prozesse (Threads vs. Prozesse) forciert, bevor er die Funktion f erstellt. Wie in der Antwort von Bartosz angegeben, haben die erzeugten Prozesse keinen Zugriff auf die neue Funktion.

def f1(x):
    ...

p = Pool(1) # p is spawned and is now an independent process, knows f1

def f(x): # p doesn't not share this object
    ...
0
yosemite_k

Das Problem, das ich hatte, wurde durch die Verwendung von if __== "__main__" gelöst, wie von Tamás aufgezeigt. In Eclipse für Windows funktionieren die Beispiele nicht unter dem Interpreter. Dies wird in erklärt http://docs.python.org/2/library/multiprocessing

0
user2226924