Search code examples
pythondictionaryvariableslocal-variables

How to acces items in dictionary as variables inside another function?


I'm writing a script that has to intitializate and read lots of variables and some files before actually calculating some stuff. Since I need to perform the calculations several times I separated the initialization from the calculations to avoid reading again and again the same files (which is quite expensive in time) and store the initial variables in a dictionary in order to always use those same variables in the calculations. What I want is to access to the items in that dictionary in a different function somthing like:

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

I've tried using **dct which, as I uderstand, would be internally translated to var1=val1, var2=val2 inside the call of the function, but I have to write in the definition of "calculations" something like:

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

since this doesn't work:

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

But depending on func1 the dictionary may have different numbers of different items/variables, and in addition it will surely have lots of items and declare them in the definition of the calculations function would be unreadable and a nightmare.

Also tried to use vars(), or local() together with update(dct) like this:

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

although in debug the var1 and var2 seems to be available before enetering to the line "result = var1*var2" I get a NameError when I try to use any of the items of the dct as variables. This method works when I call vars().update(dct) outside a function, but I need it inside the function. (The same happens when using local() instead)

Sooo...What could I do?


Solution

  • You can't do what you are asking for inside a function because local variables in a function are handled specially by the compiler. While vars (which is equivalent to locals in this context) can let you view the current values of local variables as a dictionary, you can't modify the dictionary and have it effect the real variables.

    But honestly you shouldn't need to. Variables are for the programmer and compiler to use, they should not be data. If you know the names of keys into the dictionary, use those keys as strings to index it, like normal:

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

    If the operation you're doing (e.g. var1 * var2) is itself data, then you can use something like eval and pass the dictionary of values in as the globals for the evaluation:

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

    Note that using eval (or exec) on untrusted strings is a very bad idea, since those strings could do unexpected stuff (like communicating over the network and modifying or deleting files on your hard drive). It might be safer to use your own parser that can handle only the operations you expect (e.g. arithmetic) and not all the other stuff that can be done with Python code.