Как изменить глобальный параметр внутри декоратора и автоматически сбросить его? - PullRequest
0 голосов
/ 29 мая 2019

Я пытаюсь изменить конфигурационный словарь внутри декоратора (поэтому мне не нужно связываться с кодом самой функции do_something()). Однако возникают проблемы с «сбросом» словаря в его старое состояние.

Как мне это сделать? И есть ли лучший путь вперед, чем этот подход (без изменения самого кода do_something())?

Я пробовал несколько подходов в отношении размещения переменной CONFIG, но в итоге глобальный контекст никогда не сбрасывается в исходное состояние.

import copy

CONFIG = {
    'key': 'value'
}


def alter_dictionary_decorator(function):
    def wrapper():
        old = copy.deepcopy(CONFIG)
        CONFIG['key'] = 'other_value'
        func = function()
        config = old # <- can't put 'CONFIG = old' here
        return func
    return wrapper

@alter_dictionary_decorator
def do_something():
    print(CONFIG['key'])


if __name__ == '__main__':
    print(CONFIG['key'])
    do_something()
    print(CONFIG['key'])

Ожидаемые результаты = 'значение', 'другое_значение', 'значение'

Observerd results = 'value', 'other_value', 'other_value'

1 Ответ

0 голосов
/ 29 мая 2019

Вам нужно использовать ключевое слово global для изменения переменных, имеющих глобальную область видимости.Кроме того, config = old должно было быть CONFIG = old.

Следующий код работает так, как вам нужно:

import copy

CONFIG = {
    'key': 'value'
}


def alter_dictionary_decorator(function):
    def wrapper():
        global CONFIG
        old = copy.deepcopy(CONFIG)
        CONFIG['key'] = 'other_value'
        func = function()
        CONFIG = old
        return func
    return wrapper

@alter_dictionary_decorator
def do_something():
    print(CONFIG['key'])


if __name__ == '__main__':
    print(CONFIG['key'])
    do_something()
    print(CONFIG['key'])

С выводом:

value
other_value
value
...