зафиксировать изменение значения глобальной переменной в python - PullRequest
3 голосов
/ 10 января 2020

Как обнаружить или зафиксировать изменение значения глобальной переменной в python

variable = 10
print(variable)
variable = 20 
# Detect changes to the value using a signal to trigger a function

ОБНОВЛЕНИЕ AST docs - GOOD INTRO https://greentreesnakes.readthedocs.io/en/latest/

Ответы [ 2 ]

2 голосов
/ 10 января 2020

Насколько мне известно, невозможно обобщить назначение глобального символа в Python (по крайней мере, в CPython, где глобальные значения хранятся в dict в module объекте, оба являются C типами, которые не могут быть исправлены обезьяной ).

Вот простой обходной путь, который немного компромиссен. Используйте объект-оболочку для хранения отслеживаемых переменных и определите __setattr__, чтобы делать все, что вы хотите, до (или после) установки атрибута.

class CaptureOnSetAttribute:
    def __setattr__(self, attr, value):
        # our hook to do something
        print(f'set value of {attr} to {value}')
        # actually set the attribute the normal way after
        super().__setattr__(attr, value)


wrapper_object = CaptureOnSetAttribute()

Конечно, компромисс состоит в том, что теперь вместо записи что-то вроде:

monitored_global = value

Теперь вы должны написать:

wrapper_object.monitored_attribute = value
0 голосов
/ 22 января 2020

Как насчет того, чтобы байт-код добавлял оператор печати перед каждым оператором, который сохраняется в глобальной переменной. Вот пример:

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 = 1
instr_monitor_var(test, 'a')
test()

instr_monitor_var может инструктировать функцию test, поэтому глобальная переменная a будет распечатана при изменении ее значения. Дайте мне знать, если это работает. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...