Capture Change Of Global Variable Value In Python
Solution 1:
How about instrument the bytecode to add a print statement before each statement that stores to the global variable. Here is an example:
from bytecode import *
def instr_monitor_var(func, varname):
print_bc = [Instr('LOAD_GLOBAL', 'print'), Instr('LOAD_GLOBAL', varname),
Instr('CALL_FUNCTION', 1), Instr('POP_TOP')]
bytecodes = Bytecode.from_code(func.__code__)
for i in reversed(range(len(bytecodes))):
if bytecodes[i].name=='STORE_GLOBAL' and bytecodes[i].arg==varname:
bytecodes[i:i]=print_bc
func.__code__=bytecodes.to_code()
def test():
global a
a = 1instr_monitor_var(test, 'a')
test()
instr_monitor_var
can instrument a function test
so the global variable a
will be printed out when its value is changed. Let me know if this works. Thanks!
Solution 2:
To my knowledge, it is not possible to generically capture the assignment of a global symbol in Python (At least in CPython where globals are stored in a dict
in the module
object, both are C types that cannot be monkey patched).
Here's a simple workaround that's a bit of a compromise. Use a wrapper object to store your monitored variables, and define __setattr__
to do whatever you want to do before (or after) setting an attribute.
classCaptureOnSetAttribute:
def__setattr__(self, attr, value):
# our hook to do somethingprint(f'set value of {attr} to {value}')
# actually set the attribute the normal way aftersuper().__setattr__(attr, value)
wrapper_object = CaptureOnSetAttribute()
The compromise of course is that now instead of writing something like:
monitored_global = value
You must now write:
wrapper_object.monitored_attribute = value
Post a Comment for "Capture Change Of Global Variable Value In Python"