Как получить доступ к элементам в словаре в качестве переменных внутри другой функции? - PullRequest
0 голосов
/ 06 февраля 2020

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

def func1(inputs):
    #Do some stuff to get a dictionary
    return dct

#Now having a dictionary with the variables say:
#dct={'var1':val1, 'var2':val2,...}

def calulations(dct):
    #Somehow convert the dct into var1=val1, var2=val2, ...
    result = var1*var2 #Calculate something
    return result

Я пробовал , используя ** dct, который, как я понимаю, будет внутренне переводится в var1 = val1, var2 = val2 внутри вызова функции, но я должен написать в определении «вычислений» что-то вроде:

def calculations(var1,var2, **kwargs):

, поскольку это не работает:

def calculations(**kwargs):
    result = var1*var2
    return result

Но в зависимости от func1 словарь может иметь разное количество разных элементов / переменных, и, кроме того, он наверняка будет иметь много элементов, и объявить их в определении функции вычислений будет нечитабельно и станет кошмаром.

Также попытался использовать vars () или local () вместе с update (dct) следующим образом:

def calculations(dct):
    vars().update(dct)
    result = var1*var2
    return result

хотя при отладке кажется, что var1 и var2 чтобы быть доступным перед вводом в строку "result = var1 * var2", я получаю NameError, когда пытаюсь использовать любой из элементов dct в качестве переменных. Этот метод работает, когда я вызываю vars (). Update (dct) вне функции, но он мне нужен внутри функции. (То же самое происходит при использовании local () вместо)

Оооо ... Что я мог сделать?

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

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

Но, честно говоря, вам это не нужно. Переменные предназначены для использования программистом и компилятором, они не должны быть данными. Если вы знаете имена ключей в словаре, используйте эти ключи в качестве строк для индексации, как обычно:

result = dct['var1'] * dct['var2']

Если выполняемая вами операция (например, var1 * var2) сама является данными, то Вы можете использовать что-то вроде eval и передать словарь значений в качестве globals для оценки:

result = eval('var1 * var2', dct)

Обратите внимание, что использование eval (или exec) для ненадежных строк является очень плохая идея, так как эти строки могут делать неожиданные вещи (например, общаться по сети и изменять или удалять файлы на жестком диске). Возможно, безопаснее использовать собственный синтаксический анализатор, который может обрабатывать только ожидаемых операций (например, arithmeti c), а не все другие операции, которые можно выполнить с помощью кода Python.

0 голосов
/ 06 февраля 2020

kwargs ведет себя как словарь. Чтобы извлечь из него значения, просто используйте стандартный синтаксис dict:

def calculations(**kwargs)
    result = kwargs['var1'], kwargs['var2']
    return result

dct = func1(inputs)
print(calculations(**dct))  // dict unpacking operator - passes the dict values as variable name keywords
...