Search code examples
pythonvariablesdictionarycode-readability

Dictionary items to variables


Is it possible to make simple variables from dictionaries? Something like:

dct = {'key1': val1, 'key2': val2}

should be turned to the variables key1 and key2, so that

print key1
val1
print key2
val2

Why it may be important? In my case because of readability.

I'm implementing multiple design standards in my project, to design well, stuff.

To separate the design code from the physical object being calculated I use interface functions, that get some of the objects that describe the physical object, extract the data needed and return these as dictionaries to be used in the functions doing the standard-based calculation.

Using dictionaries for this makes passing arguments easy (positional arguments would be a nightmare, kwargs yields the same problem that I have now), but results unreadable code when it comes to implementing the formulae in the standard.

An example, a rather simple formula:

_ret = (d['Da'] * d['p']) / (20 * (d['K'] / d['S']) * d['v'] + d['p']) + d['c1'] + d['c2']

vs.

_ret = (Da * p) / (20 * (K / S) * v + p) + c1 + c2

Another solution would be to make a class instead of the dict, using type(). That would result in something like:

_ret = (c.Da * c.p) / (20 * (c.K / c.S) * c.v + c.p) + c.c1 + c.c2

This is better, but not by much.

To avoid the visual noise, now I simply define new variables from all key-value pairs passed from the interface function, like

Da = d['Da']
p = d['p']

etc.

This solution is surely not the best, although it leads to easy to read code - but I couldn't come up with a 'magical' one. Do you have any suggestions how to do this transformation simply?


Solution

  • Method-1: Using vars()

    You can use the built-in function vars() to do that.

    Return the __dict__ attribute for a module, class, instance, or any other object with a __dict__ attribute.

    Without an argument, vars() acts like locals().

    In [1]: dct = {'key1': 1, 'key2': 2}
    
    In [2]: vars().update(dct) # creates variables with name as keys and value as their corresponding value of 'dct' dictionary
    
    In [3]: key1 # access 'key1' as variable
    Out[3]: 1
    
    In [4]: key2 # access 'key2' as variable
    Out[4]: 2
    

    Method-2: Using **kwargs

    Another option is to use **kwargs as suggested by @Jonrsharpe which is a cleaner approach.

    We define a function some_function having arguments as the keys of the dictionary. We call this function and pass it the dictionary dct using **kwargs option. This will give us access to the keys key1 and key2 as variables inside that function.

    In [1]: dct = {'key1': 1, 'key2': 2}
    
    In [2]: def some_func(key1, key2): # define keys as function parameters
       ...:     print key1 # print value of variable 'key1'
       ...:     print key2 # print value of variable 'key2'
       ...:  
    
    In [3]: some_func(**dct) # pass 'dct' dictionary using '**kwargs'
    1 # Value of variable 'key1'
    2 # Value of variable 'key2'