пул выдает ошибку 'локальная переменная, на которую ссылаются перед присваиванием' даже с .close () и .join () - PullRequest
0 голосов
/ 09 июля 2020

Я написал эту функцию, которая работает нормально при вызове в собственном блокноте jupyter, но когда я сохраняю блокнот как файл .py и вызываю его из другого блокнота, я получаю следующую ошибку:

UnboundLocalError: локальная переменная 'results', на которую ссылаются перед назначением

    def get_results(inputs):
        if __name__ == '__main__':
            with multiprocessing.Pool() as pool:
                results = pool.starmap(aaa.dostuff, inputs)
                pool.close()
                pool.join()
        return results

Я думал, что pool.close(), за которым следует pool.join(), заботится о порядке выполнения команд, не уверен, сделать.

1 Ответ

2 голосов
/ 09 июля 2020

Вам необходимо удалить тест if __name__ == '__main__': из вашей функции. Возможно, вы неправильно поняли, какова его цель при использовании модуля multiprocessing.

Вместо этого поместите этот на уровень модуля и поместите вызов get_results() в блок, защищенный it:

def get_results(inputs):
    with multiprocessing.Pool() as pool:
        results = pool.starmap(aaa.dostuff, inputs)
        pool.close()
        pool.join()
    return results

if __name__ == '__main__':
    # ... other code you have to produce 'inputs', that needs to run *before*
    # starting the pool of child processes, goes here ...

    results = get_results(inputs)

    # do something with the results.

Тест if __name__ редко где-либо используется, кроме как на верхнем уровне модуля. Глобальная переменная __name__ устанавливается Python при импорте модуля. Только когда вы запускаете свой файл как скрипт (с python path/to/file.py), Python устанавливает эту переменную в строку "__main__", и это удобное значение для проверки, когда вы хотите запускать код только тогда, когда текущий модуль является отправной точкой.

В зависимости от вашей ОС и конфигурации, при использовании multiprocessing Python создает новые, отдельные дочерние процессы, которые либо начинаются с копии состояния интерпретатора Python, либо с специализированный многопроцессорный скрипт, специально разработанный для запуска многопроцессорного рабочего кода. Ваш собственный сценарий больше не является основной отправной точкой, и значение __name__ будет другим.

Что пошло не так в вашем случае, так это то, что вы почти наверняка вызвали get_results() в рабочем процессе , где __name__ означает другое значение. В этот момент ваша функция выполняет две строки:

  • if __name__ == '__main__': - Результат False, поэтому блок пропускается
  • return result - ошибка! Ничто не устанавливает значение для этого локального имени, поэтому оно все еще не привязано.
...