Motivation: I want to dynamically define global variables and assign values in functions!
(You can't do this with Hoi Hoi ...)
def dainyuu(val_name):
global val
val = 123 #I want to assign to a variable with the name specified here
dainyuu("val")
print(val) #Reference outside the function
exec()
It is possible to define and assign dynamic variables by, but I summarized it because it took some time to assign to global variables.
The verification is Python 3.7.3.
--Official reference: Built-in function #exec
--Pass `globals ()`
as the second argument of exec
--Do not pass the third argument
exec
Toglobals()
By passing only, the assignment in the string becomes an assignment to a global variable.
#Unless otherwise specified, it will be the definition of a local variable
def define_variable_test1(var_name):
exec("{0} = 123".format(var_name))
eval("print('{0}(in) : ' + str({0}))".format(var_name))
# globals()Will be the definition of a global variable
def define_variable_test2(var_name):
exec("{0} = 345".format(var_name), globals())
eval("print('{0}(in) : ' + str({0}))".format(var_name))
define_variable_test1("val1")
try:
print("val1(out): {0}\n".format(val1))
except NameError:
print("val1(out): not defined\n")
define_variable_test2("val2")
try:
print("val2(out): {0}\n".format(val2))
except NameError:
print("val2(out): not defined\n")
out
val1(in) : 123
val1(out): not defined
val2(in) : 345
val2(out): 345
--Pass globals ()` `` and
locals () `` to
ʻexec``` --Declare ``
global` `` variables in the evaluation statement
exec
Tolocals()
If you pass, the assignment in the string becomes a local variable, but in the same stringglobal
By declaring it, you can assign it to a global variable.
# locals()If you also pass it, it will be a definition of a local variable
def define_variable_test3(var_name):
local_val = 12345
exec("{0} = local_val".format(var_name), globals(), locals())
eval("print('{0}(in) : ' + str({0}))".format(var_name))
#Declaration of a global variable in exec makes it a definition of a global variable
def define_variable_test4(var_name):
local_val = 34567
exec("global {0}\n{0} = local_val".format(var_name), globals(), locals())
eval("print('{0}(in) : ' + str({0}))".format(var_name))
define_variable_test3("val3")
try:
print("val3(out): {0}\n".format(val3))
except NameError:
print("val3(out): not defined\n")
define_variable_test4("val4")
try:
print("val4(out): {0}\n".format(val4))
except NameError:
print("val4(out): not defined\n")
out
val3(in) : 12345
val3(out): not defined
val4(in) : 34567
val4(out): 34567
Speaking of course, it is natural, but I was worried because I could pass `global ()`
as an argument ...
Or rather, I'm talking about trying to stop the act of walking such an evil way.
This is the information sent to the comments. It's black magic ...!
# globals()It is also possible to directly edit the dictionary returned by
def define_variable_test5(var_name):
local_val = 1234567
globals()[var_name] = local_val
eval("print('{0}(in) : ' + str({0}))".format(var_name))
define_variable_test5("val5")
try:
print("val5(out): {0}\n".format(val5))
except NameError:
print("val5(out): not defined\n")
out
val5(in) : 1234567
val5(out): 1234567
Substitution is successful normally, but to be honest, I don't think it is a recommended practice, so please be careful. The behavior may change in the future.
Note that `globals () ``` succeeded, but
`locals () ``` failed to assign in the function. (Changes are not reflected in actual local variables)
** Note **: The contents of this dictionary must not be changed; changes do not affect the values of local or free variables used by the interpreter.
def changing_local_variable_test():
var = 123
print("before: {0}".format(var))
locals()["var"] = 234
print("after: {0}".format(var))
changing_local_variable_test()
out
before: 123
after: 123
Recommended Posts