многопроцессорному процессу python не удается получить атрибут

У меня есть функция:

downloadXMLPool = Pool(processes=3)
downloadFile = Pool(processes=3)


def dl_data_and_convert(url,formatIn,retry=True,noHTML=False,downloadSpecialPool=None):
    if downloadSpecialPool == None:
        dlPool = downloadXMLPool
    else:
        dlPool = downloadSpecialPool

    if formatIn == 'xml':
        return dl_xml_to_dict(url,dlPool,retry=retry,noHTML=noHTML)
    elif formatIn == 'json':
        return dl_json_to_dict(url,dlPool,retry=retry,noHTML=noHTML)


def dl_xml_to_dict(url,dlPool,retry=True,tryNumber=1,noHTML=False):
    try:
        response = None
        doc = xmltodict.parse(dlPool.apply_async(requests.get, (url,)).get().content)

        if noHTML:
            if 'html' in doc:
                if retry:
                    sleep(randrange(60,120)*tryNumber)
                    return dl_xml_to_dict(url,dlPool,tryNumber=tryNumber+1,noHTML=noHTML)
        return doc

    except Exception as e:
        if retry and request_error_tester(tryNumber,url,response,e):
            return dl_xml_to_dict(url,dlPool,tryNumber=tryNumber+1,noHTML=noHTML)
        else:
            return None

Эти две функции работают нормально.

И они у меня есть:

def download_file(url, NameFile, folder='./', retry=True, downloadSpecialPool=None):
    if downloadSpecialPool == None:
        return launch_dl_in_file(url, downloadFile, NameFile, folder=folder, retry=retry)
    else:
        return launch_dl_in_file(url, downloadSpecialPool, NameFile, folder=folder, retry=retry)


def launch_dl_in_file(url, dlPool, NameFile, folder='./', retry=True, tryNumber=1):
    try:
        dlPool.apply_async(dl_in_file, (url, NameFile, folder)).get()
        return True

    except Exception as e:
        if match('.*HTTP Error 504.*',str(e)) != None:
            if retry:
                if tryNumber < 21:
                    sleep(15*tryNumber)
                    return launch_dl_in_file(url, dlPool, NameFile, folder=folder, tryNumber=tryNumber+1)
        print_screen_error("Download error for file : "+url+"\n\tError : "+str(e)+"\n")
        return False


def dl_in_file(url, NameFile, folder='./'):
    with closing(urllib.request.urlopen(url)) as r:
        with open(os.path.join(folder,NameFile), 'wb') as f:
            shutil.copyfileobj(r, f)
    return True

И я получаю эту ошибку:

AttributeError: Can't get attribute 'dl_in_file' on <module 'tools' from '/home/*/src/tools.py'>

Я пробовал некоторые модификации: использовать другой многопроцессорный пул, использовать downloadXMLPool, новую функцию и т. Д. У меня все еще была та же проблема.

Process ForkPoolWorker-4:
Traceback (most recent call last):
  File "/usr/lib/python3.7/multiprocessing/process.py", line 297, in _bootstrap
    self.run()
  File "/usr/lib/python3.7/multiprocessing/process.py", line 99, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.7/multiprocessing/pool.py", line 110, in worker
    task = get()
  File "/usr/lib/python3.7/multiprocessing/queues.py", line 354, in get
    return _ForkingPickler.loads(res)
AttributeError: Can't get attribute 'dl_in_file' on <module 'tools' from '/home/*/src/tools.py'>

Что я здесь делаю не так?


person studyfranco    schedule 11.12.2020    source источник
comment
Это решение не работает. Если я перемещу dl_in_file до launch_dl_in_file, и у меня всегда будет один и тот же результат. Если я использую dl_in_file в download_file, у меня такая же проблема. И я не понимаю почему. Я использую ту же логику в другом программном обеспечении. У меня проблема только с этими функциями.   -  person studyfranco    schedule 14.12.2020
comment
Связанный ответ сообщает вам, что создание экземпляра Pool до, которое вы определите для своих функций, не будет работать, вам сначала нужно определить все функции, которые вы хотите использовать в дочернем процессе.   -  person Darkonaut    schedule 14.12.2020
comment
Я так не понял. Я модифицирую свой код, и он работает хорошо! Я так удивлен. Это очень странно. Спасибо за помощь   -  person studyfranco    schedule 14.12.2020


Ответы (1)


Так что с помощью Darkonaut у меня есть решение. Исходный поток: Карта пула многопроцессорной обработки Python: AttributeError: не удается обработать локальный объект

Решение простое, вам нужно переехать:

downloadXMLPool = Pool(processes=3)
downloadFile = Pool(processes=3)

после ваших функций.

person studyfranco    schedule 14.12.2020