еще одна путаница с ошибкой многопроцессорности, у объекта 'module' нет атрибута 'f' - PullRequest
62 голосов
/ 06 мая 2010

Я знаю, что на этот вопрос уже отвечали, но кажется, что выполнение сценария напрямую "python filename.py" не работает. У меня есть Python 2.6.2 на SuSE Linux.

Код:

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

Командная строка:

> 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'

Ответы [ 5 ]

120 голосов
/ 06 мая 2010

Перестройте ваш код так, чтобы функция f() была определена до создания экземпляра пула. В противном случае работник не сможет увидеть вашу функцию.

#!/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])
5 голосов
/ 06 мая 2010

Это работает:

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

def f(x):
    return x*x

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

Я не уверен на 100%, почему ваш код не работает, но я думаю, причина в том, что дочерние процессы, запущенные модулем multiprocessing, пытаются импортироватьосновной модуль (чтобы иметь доступ к определенным вами методам), и раздел if __name__ == "__main__" требуется, чтобы не выполнять код инициализации, в котором вы настраивали свой пул.

1 голос
/ 14 ноября 2018

Это происходит из-за того, что при p = Pool(1) главный процесс разветвляет процессы (потоки против процессов), прежде чем создает функцию f. Как указано в ответе Бартоша, порожденные процессы не имеют доступа к новой функции.

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
    ...
1 голос
/ 30 марта 2013

Проблема, с которой я столкнулся, была решена с помощью if __name__ == "__main__", как указал Тамас; в Eclipse для Windows примеры не работают под интерпретатором. Это объясняется в http://docs.python.org/2/library/multiprocessing

1 голос
/ 13 октября 2012

Возможно, ваш файл python имеет то же имя, что и модуль:

  • test.py
  • тест /
    • __ __ INIT. Ру

в pickle.py вы получаете сообщение об ошибке:

    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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...