python декоратор изменяет переменную - PullRequest
0 голосов
/ 19 июня 2020

Я пытаюсь использовать декоратор для изменения значения переменной в python с помощью следующего кода

def config(func):
    def new_function():
        func()
        print(lr)
    return new_function
import ex
@ex.config
def config():
    lr = 0.1
    globals().update(locals())
config()

Я хотел бы распечатать 0,1, но была показана ошибка с неопределенной переменной. Есть ли способ добиться этого без изменения func_a?

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Короче нет. Здесь func_a() объявляет и назначает lr как локальную переменную. Вы можете исправить это, добавив ключевое слово global:

lr = 0
def config(func):
    def new_function(*args,**kwargs):
        func(*args,**kwargs)
    return new_function
@config
def func_a():
    global lr
    lr = 0.1
func_a()
print(lr)

Но использование ключевого слова global раздражает и может вызвать ошибки, если вы его забудете, поэтому вам может быть лучше вернуть:

lr = 0
def config(func):
    def new_function(*args,**kwargs):
        return func(*args,**kwargs)
    return new_function
@config
def func_a():
    return 0.1
lr = func_a()
print(lr)

Редактировать

Вы могли бы поместить его в класс как-то так:

# Make an empty class:
class Foo: pass
# Or if you want to initalize the variables:
class Foo:
    def __init__(self):
        lr = 0
f = Foo()

# The decorator doesn't make much of a difference
def func_a():
    f.lr = 0.1

func_a()
print(f.lr)

Теперь, если вы хотите сохранить абсолютно все локальные переменные, которые определяет func_a, вы можете сделать это:

def func_a():
    lr = 0.1
    f.__dict__.update(locals())
0 голосов
/ 19 июня 2020

'lr' - это локальная переменная, и вы не сохраняли и не возвращали ее значение. Поэтому вы можете просто получить значение глобальной переменной 'lr' в первой строке, и ее значение равно 0.

...