Reputation: 13
I'm working on large Finite Element Analysis code with a lot a functions. To pass variables between different functions I make use of python's kwargs. I mainly opted for this so that I can call the functions in a lot of different ways, creating a great flexibility.
However now I'm dealing with a problem. From a main function I call another function using the kwargs. This second function then processes the input and adds new kwargs. The problem is that the new kwargs created in that function are not accessible in the first one. Is there a pythonic way of doing this? I created the following code as an example:
# Create main function
def main(**kwargs):
# Add a key word argument
kwargs["textMain"] = "text added in main"
# Call a function with existing kwargs and a new one
functionA(textNew = "text added in new" ,**kwargs)
# Test what is in kwargs after subfunction is called
print("\nTest kwargs after subfunction is called:")
if "textMain" in kwargs:
print(kwargs["textMain"])
if "textNew" in kwargs:
print(kwargs["textNew"])
if "textA" in kwargs:
print(kwargs["textA"])
def functionA(**kwargs):
# Test kwargs before adding kwargs in subfunction
print("\nTest kwargs in subfunction before adding:")
if "textMain" in kwargs:
print(kwargs["textMain"])
if "textNew" in kwargs:
print(kwargs["textNew"])
if "textA" in kwargs:
print(kwargs["textA"])
# Add kwargs
kwargs["textA"] = "text added in sub A"
# and test kwargs again
print("\nTest kwargs in subfunction after adding:")
if "textMain" in kwargs:
print(kwargs["textMain"])
if "textNew" in kwargs:
print(kwargs["textNew"])
if "textA" in kwargs:
print(kwargs["textA"])
if __name__ == "__main__":
main()
This yields the following output:
#Test kwargs in subfunction before adding:
#text added in main
#text added in new
#Test kwargs in subfunction after adding:
#text added in main
#text added in new
#text added in sub A
#Test kwargs after subfunction is called:
#text added in main
where my prefered output would be:
#Test kwargs in subfunction before adding:
#text added in main
#text added in new
#Test kwargs in subfunction after adding:
#text added in main
#text added in new
#text added in sub A
#Test kwargs after subfunction is called:
#text added in main
#text added in new
#text added in sub A
It would be of great help if any one could solve my problem. Thanks in advance!
Upvotes: 1
Views: 669
Reputation: 1121366
When you use the **kwargs
syntax in a call expression, Python expands the dictionary and passes in separate arguments. The same syntax in the function signature then tells Python to create a new dictionary in that function to capture the keyword arguments.
In other words, kwargs
in main()
is not the same dictionary as the one in functionA()
.
Either pass in the actual dictionary (not using **kwargs
syntax) or have functionA()
return a new dictionary.
Passing in kwargs
as a single argument lets you alter the dictionary from functionA()
and see the changes reflected in main()
, as they now share a reference to the same dictionary:
def main(**kwargs):
functionA(kwargs, textNew="text added in new")
# ... etc ...
def functionA(mapping, **kwargs):
# do something with mapping, it is the same dictionary as kwargs in main
Returning the updated kwargs
dictionary from functionA()
requires that you assign the new object back to kwargs
in main()
:
def main(**kwargs):
kwargs = functionA(textNew="text added in new", **kwargs)
# ... etc ...
def functionA(**kwargs):
# ...
return kwargs
Upvotes: 2