>>> def fn(sc):
... exec(sc)
This function runs perfectly fine.
I think that executing "A4 = A4+1" inside fn without indicating that A4 is a global doesn't affect the global variable, since each function has its own local dictionary of variables.
If you need your fn to be a separate function containing an exec call, you can specify that your variable is a global, using the global keyword.
>>> def fn(sc):
... exec(sc)
...
>>> value = 1
>>> fn('value += 1')
>>> value
1
>>> fn('global value; value += 1')
>>> value
2
Alternatively, exec will accept explicit globals and locals dictionaries passed into it. The help info for these functions notes that you can't reliably alter the value of a variable by updating locals(), but you can with globals(). As long as globals are what you want to update, you don't need to pass locals().
>>> def fn(sc):
... exec(sc, globals())
...
>>> value = 1
>>> fn('value += 1')
>>> value
2
exec(). And clearly fn is not just an alias, since the namespace targets are different.locals() and globals() return the same thing. As long as you only want to alter global variables, passing globals() as both dictionaries should work.
globalstatements, explicitly referenceglobals()['A4'] = A4 + 1, or tellexec()what local namespace to update.