0

I have a global variable with a variable name, so using it is a bit difficult. (Yes, go ahead and tell me that exec is a bad solution, because I would be happy to learn a better one.) This is within a function that I need to run recursively, so global variables can only be used with extreme caution. In addition, the function creates new variables and I can't say beforehand what they will be. This recursive function was working until I added the pickle parts, to save and restore variables and avoid unnecessary repetitions of the calculations. Here is a snippet:

strVar = 'c%sc%dX' % (strJ, kIn)    
fName =  '%s\\%s.pckl' % (pickle_dir, strVar)    
if os.path.isfile(fName):
    #retVal = 0 # default to avoid undefined error
    strSym = 'retVal = %s' % (strVar)
    exec(strSym, globals(), locals())
    return retVal
    #strSym = 'global %s; return %s' % (strVar, strVar)
    #exec(strSym, globals()) 

In the current test, when this code is run the first time, strVar contains a string with the name of the variable, i.e. 'cm1c0X' and the variable cm1c0X is global and contains the value integer 0.

In the line "return retVal", Visual Studio puts a wavy underline under retVal and says it is not defined. When I run the code, this statement produces an exception saying that the local variable 'retVal' is referenced before assignment. Also, retVal does not appear in the list of local or global variables.

My guess: the exec statement does in fact work, and produces the variable retVal within the scope of exec, but not within the scope of my "if" statement. When I use the last 2 lines instead of this, I get "return outside function", so presumably the return statement is in the scope of exec and not within the scope of the "if" statement or the function surrounding it.

So, I am looking for some way to assign a global variable to a local variable that is within the scope of my code. Maybe I need to use something other that globals() and locals(). I read that I could use a custom-built dictionary, but the example code didn't explain what needs to come after the colon in the dictionary, so I haven't understood it yet.

Tom Ligon
  • 31
  • 3
  • This way lies madness. Solve your problem in a way which doesn't require using `exec` to access variables whose names you don't know. – kaya3 Feb 10 '22 at 18:50
  • Thanks, this helped me find a solution, and it doesn't require exec. Since I have the name of the variable in strVar, I can access the variable with globals()[strVar] for reading or writing it. Since I have no exec, the local variables are in the right context, and support reentrant programming of the recursive function. By the way, I also understand that creating a database instead of using pickle would be a better solution, but I will probably postpone that as long as this solution is working. – Tom Ligon Feb 11 '22 at 22:46
  • I'm glad that it helped you solve your problem. That said, I would recommend using your own dictionary for this rather than `globals()`; if these variables are always accessed dynamically via `globals()` then it should work the same if you use any other dictionary, but your code will be easier to understand and less likely to have bugs. – kaya3 Feb 11 '22 at 22:48
  • I have now converted from using globals() to using a private dictionary. The problem I am working on was created in a paper that was written long before computers were invented, and the author used some unorthodox notation. Now I have converted all of this to functions, and the most important one is working recursively. Then I discovered that I was only using the globals() notation inside of functions, where I check to see if it has already been calculated or add it to the dictionary, which is stored via pickle. Pickle is now used only for this one dictionary, no longer for all variables. – Tom Ligon Feb 17 '22 at 08:58

0 Answers0