web-dev-qa-db-fra.com

encore une confusion avec une erreur de multitraitement, l'objet 'module' n'a pas d'attribut 'f'

Je sais que cela a été répondu auparavant, mais il semble que l'exécution du script directement "python filename.py" ne fonctionne pas. J'ai Python 2.6.2 sur 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])

Ligne de commande:

> 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

Restructurez votre code afin que la fonction f() soit définie avant de créer une instance de Pool. Sinon, le travailleur ne peut pas voir votre fonction.

#!/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

Celui-ci fonctionne:

#!/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])

Je ne suis pas sûr à 100% de la raison pour laquelle votre code ne fonctionne pas, mais je suppose que la raison en est que les processus enfants lancés par le module multiprocessing tentent d'importer le module principal (pour accéder aux méthodes que vous avez définies), et la strophe if __== "__main__" est requis pour ne pas exécuter le code d’initialisation où vous avez configuré votre pool.

5
Tamás

Une possibilité est que votre fichier python porte le même nom qu'un module:

  • test.py
  • tester/
    • __init__.py

dans pickle.py, vous avez l'erreur venant de:

    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

Cela vient du fait qu'avec p = Pool(1) le processus principal forque les processus (threads vs processus) avant de créer la fonction f. Comme indiqué dans la réponse de Bartosz, les processus générés n’ont pas accès à la nouvelle fonction.

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

Le problème que j'ai eu a été résolu en utilisant if __== "__main__" comme l'a souligné Tamás; Dans Eclipse pour Windows, les exemples ne fonctionnent pas sous l'interpréteur. Ceci est expliqué dans http://docs.python.org/2/library/multiprocessing

0
user2226924