So let's say I have this function with a lot of variable setting:
def set_variables():
var_a = 10
var_b = 200
and these variables need to be set in multiple functions and accessed via their var name. Is there a way to create this function s.t. after it's call the parent function that calls it has var_a and var_b without having to return them? The function above is an example, but in reality there are a lot of variables so it's not really viable to have something like the below.
def parent_function():
var_a, var_b, ... = set_variables()
ideally I'd like something like
def parent_function():
set_variables()
# do some code with var_a or var_b
Or maybe even return a dict of key, val and automatically generate variables of key name set to val.
So for example
def parent_function():
var_dict = set_variables()
some_func_to_auto_set_vars_from_dict(var_dict)
# Do something with var_a or var_b
2 Answers 2
Return a collection that lets you access the values by name without having to re-assign them, e.g. a dict:
def set_variables():
return {
'a': 10,
'b': 200,
}
def parent_function():
v = set_variables()
# do some code with v['a'] or v['b']
Or (my personal preference for this use case) a NamedTuple, which gives you the benefit of type checking (and IDE autocomplete, exactly as if you were using top-level named vars):
from typing import NamedTuple
class Vars(NamedTuple):
a: int
b: int
def set_variables() -> Vars:
return Vars(a=10, b=200)
def parent_function():
v = set_variables()
# do some code with v.a and v.b
3 Comments
NamedTuple IMO -- expanded answer a bit to show how that works.vars is a built-in function that you're shadowing.It may seem easy to let all functions set all variables. But this implicit sharing of state has proven to become a maintenance nightmare.
Rather, use immutable dataclasses; they provide more or less the convenience you request, but allow for much easier reasoning about the code.
@dataclass
class Settings:
a: str =""
b: int =5
...
def parent():
s = initialize(Settings(c=[1,2,3]))
use(s.a, s.b)
...
def initialize (s: Settings):
return dataclass.replace(s,
b=10, d="@#$_"
)
set_variablesreturn a value, just return a singledictinstead of multiple values.set_variables()were to simply return whatever variables necessary, you could then just pass those variables toparent_function().