Область видимости переменной вложенной функции Python - PullRequest
0 голосов
/ 24 августа 2018

У меня есть следующие функции:

def print_hamming_distance(calls):
    #calls is a dictionary
    samples = calls.keys() 
    with Pool(8) as pool: #Parallel Process
        for dist, sample1, sample2 in pool.imap(multi_proc_hamming_distance, itertools.combinations(samples,2)):
            print( dist, sample1, sample2 )   

def multi_proc_hamming_distance(samples): # specifically created function to use with pool
    return hamming_distance(calls[samples[0]],calls[samples[1]]), samples[0], samples[1]

Когда я вызываю их в своем коде, я получаю эту ошибку:

NameError: name 'calls' is not defined

У меня сложилось впечатление, что вложенные функции могут обращаться к переменным вне этой функции. Может кто-нибудь объяснить мне, почему я получаю эту ошибку?

Я понимаю, что одним из решений является просто передача словаря в качестве аргумента второй функции, которая была, как я решил проблему, но это увеличило время выполнения. Кроме того, когда я запустил код на jupyter без упаковки print_hamming_distance (звонки), это сработало.

без упаковки, я имею в виду так:

def multi_proc_hamming_distance(samples): # specifically created function to use with pool
    return hamming_distance(calls[samples[0]],calls[samples[1]]), samples[0], samples[1]


#calls is already defined somewhere
samples = calls.keys() 
with Pool(8) as pool: #Parallel Process
    for dist, sample1, sample2 in pool.imap(multi_proc_hamming_distance, itertools.combinations(samples,2)):
        print( dist, sample1, sample2 )

Редактировать: ошибка полной трассировки

multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
  File             "/home/usr/anaconda3/envs/some_env/lib/python3.5/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "/usr/project/pipeline/project_name/distance.py", line 44, in multi_proc_hamming_distance
return hamming_distance(calls[samples[0]],calls[samples[1]]), samples[0], samples[1]
NameError: name 'calls' is not defined
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/project/pipeline/project_name.py", line 264, in <module>
main()
File "/usr/project/pipeline/project_name.py", line 259, in main
distance(param)
File "/usr/project/pipeline/project_name.py", line 169, in distance
distance = get_distance[param.data_type](calls)
File "/usr/project/pipeline/project_name/distance.py", line 37, in get_param_type_distance
for dist, sample1, sample2 in pool.imap(multi_proc_hamming_distance, itertools.combinations(samples,2)):
File "/home/usr/anaconda3/envs/some_env/lib/python3.5/multiprocessing/pool.py", line 731, in next
raise value

1 Ответ

0 голосов
/ 24 августа 2018

Да, вложенные функции могут обращаться к переменным вне этой функции. Но в вашем случае переменная звонков не определена внутри функции, она является только аргументом и не может быть доступна для вложенной функции. Вы можете исправить это, добавив calls = calls следующим образом.

def print_hamming_distance(calls):
    #calls is a dictionary
    calls = calls
    samples = calls.keys() 
    with Pool(8) as pool: #Parallel Process
    for dist, sample1, sample2 in pool.imap(multi_proc_hamming_distance, itertools.combinations(samples,2)):
        print( dist, sample1, sample2 )   

    # nested function
    def multi_proc_hamming_distance(calls,samples): # specifically created function to use with pool
        return hamming_distance(calls[samples[0]],calls[samples[1]]), samples[0], samples[1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...