Home > Software design >  Is there a way to convert a string into a function parameter and send it like this?
Is there a way to convert a string into a function parameter and send it like this?

Time:08-10

Consider the following function:

def config(text=None, background=None, foreground=None):
    # Configures text, background and foreground.

# Reconfiguration example
config(text='Hello', foreground='#000000') # Would reconfigure text and fg, but not bg.

Now, supposing I had a list of what to reconfigure and how to reconfigure, such as [['text', 'World'], ['background', '#ffffff']], is there a way for me to pass that 'text' and 'background' as the function parameters like the following?

parameters_and_values = [['text', 'World'], ['background', '#ffffff']]
for group in parameters_and_values:
    config(group[0]=group[1]) # Example: config('text'='World') 

The code above would obviously fail because 'text' would be considered as a string, and not as the "text" parameter inside of the parameters of the "config" function. But is there a way to convert that 'text' string into the actual "text" parameter inside of the function definition?

Maybe something like:

parameters_and_values = [['text', 'World'], ['background', '#ffffff']]
for group in parameters_and_values:
    config(vars()[group[0]]=group[1]) # Example: config(vars()['text']='World') 

Note: The vars() code also doesn't work, because it assumes "text" is a variable outside of the function, not its parameter.

Motivation:
I'm developing an application using Tkinter and the widget reconfigurations must come from an outside list, they cannot be inserted directly. The real code is as follows (and it fails):

def reconfigurations([argument_list]):
    ''' 
    Reconfigures tkinter widgets using a dictionary of conditions 
    and what to reconfigure if such conditions are met.
    '''
    canvas_obj = argument_list[0] # None if there's no canvas related to this widget, or if the widget_obj is a canvas.
    widget_obj = argument_list[1] # Is the widget to be reconfigured.
    relation_dictionary = argument_list[2] # Example: {(True): [[relief, FLAT], ['bg', '#05ad32']]}, (False): [[relief, SUNKEN], ['bg', '#ffffff']]}
    results_of_examination = tuple(argument_list[3]) # Example: [True] < Always a list that needs to become a tuple. Will be compared with relation_dictionary to see which reconfigurations shall be done.
     
    for key in relation_dictionary:
        everything_checks = True # Assume that results_of_examination==key 
        for counter in range(0,len(key)):
            if key[counter] != results_of_examination[counter]:
                everything_checks = False
        if everything_checks: 
            for command_list in relation_dictionary[key]: # Example: [relief, FLAT]
                # Command_list[0] may be bg, state, fg, highlightbackground, relief, text, width, height, font or place. 
                if canvas_obj != None: # If widget_obj is a canvas-related object.
                    if command_list[0] == 'place':
                        canvas_obj.moveto(widget_obj, command_list[1][0]*rfx, y=command_list[1][1]*rfy) # rfx and rfy are variables that resize placings for different monitor sizes. They are global definitions. 
                    else:
                        **canvas_obj.itemconfig(widget_obj, vars()['{command_list[0]}'] == command_list[1])**
                else: # Any other widget_obj
                    if command_list[0] == 'place': # Place example: [{(True): [place, [200, 400]]}, {(False): [place, [400, 800]]}]
                        widget_obj.place(x=command_list[1][0]*rfx, y= command_list[1][1]*rfy)
                    else:
                        **widget_obj.config(vars()[f'{command_list[0]}'] == command_list[1])**

CodePudding user response:

Convert your list of lists into a dict, and then use the ** operator to pass the dict as kwargs.

Given the list of lists:

parameters_and_values = [['text', 'World'], ['background', '#ffffff']]

you can call your config function as:

config(**dict(parameters_and_values))

which is exactly equivalent to:

config(text='World', background='#ffffff')
  • Related