2

I have a dictionary which is going to be passed to multiple functions. In each of the functions, I need to extract all the values of the dictionary.

For example,

def foo(mas_details):
    # Extract mas details
    if 'ip' in mas_details.keys():
        mas_ip = mas_details['ip']
    else:
        logger_object.critical("MAS IP not provided!")
        return False
    if 'username' in mas_details.keys():
        mas_username = mas_details['username']
    else:
        mas_username = 'root'
    if 'password' in mas_details.keys():
        mas_password = mas_details['password']
    else:
        mas_password = 'root'
    if 'protocol' in mas_details.keys():
        mas_protocol = mas_details['protocol']
    else:
        mas_protocol = "http"
    if 'timeout' in mas_details.keys():
        mas_timeout = mas_details['timeout']
    else:
        mas_timeout = 120

I have about 15 functions where I will be passing this mas_details dictionary. However, extracting the values in each function makes the code repetitive.

I want to put the extraction of the values into a function in itself. However, if I do that, the variables won't be accessible in the parent functions, unless I make all the variables global.

What is the best way of going about this?

7
  • return the extracted values as a tuple? Commented Aug 10, 2016 at 10:01
  • Do you actually use all the 15 variables in all the functions? Commented Aug 10, 2016 at 10:01
  • Look into wrapping those functions with a decorator that handles the dictionary part Commented Aug 10, 2016 at 10:03
  • @BasicWolf, I have only one dictionary. I have 15 functions, and about 5-6 variables in the dictionary. I use all the keys of the dictionary in each of the 15 functions. Commented Aug 10, 2016 at 10:08
  • 1
    Is it necessary to make them as 15 separate variables? Can you modify your code so that those functions will access a cleaned dict instead? Commented Aug 10, 2016 at 10:10

2 Answers 2

2

The code can be made a lot smaller:

'username' in mas_details.keys():

The keys() is superfluous, it's equal to

'username' in mas_details

But more importantly,

if 'username' in mas_details.keys():
    mas_username = mas_details['username']
else:
    mas_username = 'root'

is equal to

mas_username = mas_details.get('username', 'root')

The get function takes a default to use if the key doesn't exist.

But: what you have is some group of variables together with some functionality that always acts on the variables. That is what we invented the class for:

class MasDetails(object):
    def __init__(self, mas_details):
        self.username = mas_details.get('username', 'root')
        self.password = mas_details.get('password', 'root')

Et cetera. Then just pass in a MasDetails instance and use its .username property.

mas = MasDetails(mas_details)

def foo(mas):
    # use mas.username, mas.password here

If you have any functionality that only uses these properties, put it on this class as methods.

In particular, maybe your foo function and the 14 others should simply be methods on the MasDetails class, then they can use self.username.

Sign up to request clarification or add additional context in comments.

Comments

0

Well, if you simply need all the 6 variables in a function, you can destruct the dictionary, i.e.

def f1(arg1, arg2, ..., arg6):
   ...

def f2(arg1, arg2, ..., arg6):
   ...

# initialize dictionary
d = {'arg1': 'val1', 'arg2': 'val2', ...}

# fill default values (or use defaultdict with appropriate factory)
d['arg1'] = d.get('arg1', 'default_arg1_value')
d['arg2'] = d.get('arg2', 'default_arg2_value')
...

f1(**d)
f2(**d)
...

This would give you an access to variables, without explicit extraction from a dictionary. One of the good practices is to keep the number of arguments limited, so consider initializing the dict with default values once, and then using **kwargs and extracting the required values manually, in case the number of arguments grows.

# 1. Initialize dictionary
# 2. Fill default values
# 3. Use with kwargs:

def f(**kwargs):
    arg1 = kwargs['arg1'] # at this point you are SURE, that there is a value  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.