[Python3] Dynamically define global variables in functions

Introduction

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

Pattern 1: Simple definition of global variables

--Pass `globals ()` as the second argument of exec --Do not pass the third argument

execToglobals()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

Pattern 2: Use local variables to define global variables

--Pass globals ()` `` and locals () `` to ʻexec``` --Declare `` global` `` variables in the evaluation statement

execTolocals()If you pass, the assignment in the string becomes a local variable, but in the same stringglobalBy 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.

Pattern 3: Directly edit the return value of ``` globals ()` ``

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)

Built-in functions #locals ()

** 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

[Python3] Dynamically define global variables in functions
Using global variables in python functions
Dynamically define functions (methods) in Python
How to dynamically define variables in Python
Practice applying functions and global variables in Python
Dynamically import scripts in Python
Handle environment variables in Python
Overriding library functions in Python
A note on handling variables in Python recursive functions
Dynamically call methods in Python
Python functions learned in chemoinformatics
How to define multiple variables in a python for statement
Initializing global variables using Python decorators
[python] Manage functions in a list
Landmines hidden in Python class variables
Dynamically load json type in python
[Python] It seems that global variables cannot be referenced in Multiprocessing
[Python] Variables
Python functions
Python3> Functions> Symbol table> Assign to variables / Reference variables / Global variables / globals () / locals ()
How to access environment variables in Python
Easily use your own functions in Python
Pharmaceutical company researchers summarized functions in Python
Difference between nonlocal and global in Python
The story of manipulating python global variables
To reference environment variables in Python in Blender
New features in Python 3.4.0 (3)-Single-dispatch generic functions
How to dynamically zero pad in Python
Pharmaceutical company researchers summarized variables in Python
Python in optimization
CURL in python
Metaprogramming in Python
Python 3.3 in Anaconda
Geocoding in python
SendKeys in Python
Meta-analysis in Python
Python variables and data types learned in chemoinformatics
Unittest in python
Find unused classes / methods / functions / variables in vulture
[python] Difference between variables and self. Variables in class
Epoch in Python
Discord in Python
To dynamically replace the next method in python
GNU GLOBAL (gtags) + α in Go, Ruby, Python
Sudoku in Python
DCI in Python
A note on optimizing blackbox functions in Python
quicksort in python
nCr in python
N-Gram in Python
Programming in python
Plink in Python
Constant in python
#Python basics (functions)
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
[Beginner] Python functions
StepAIC in Python
Get files, functions, line numbers running in python
N-gram in python