Используйте словарь для ссылки на глобальную переменную внутри функции (Python) - PullRequest
0 голосов
/ 27 января 2020

Я использую словарь для ссылки на глобальную переменную в Python внутри функции. Я хочу использовать функцию для обновления глобальной переменной. (На самом деле мои глобальные переменные более сложны, чем это.)

global_variable_A=5
global_variable_B=1
dictionary={'A':global_variable_A,'B':global_variable_B}

def f(x,glob):
    global global_variable_A
    dictionary[glob]+=x

f(2,'A')
print(global_variable_A)

Это возвращает 5, а не 7. Я понимаю, почему, в любом случае, нужно сообщить Python, что я имею в виду переменную dictionary[glob] ссылаться на глобальную, а не на локальную переменную, при этом все еще ссылаясь на переменную через словарь?

Спасибо за ваше время и извинения, если я пропустил что-то совершенно очевидное.

Ответы [ 2 ]

0 голосов
/ 27 января 2020

Когда вы присваиваете значение имени name = 5, вы создаете ссылку на 5, которую вы можете использовать для доступа к идентификатору name. Обычно, если у вас есть какой-то код с более узкой областью действия, вы можете использовать эту ссылку

def f():
    print(name)

или создать локальную ссылку, используя тот же идентификатор, потенциально для несвязанного значения

def g():
    name = 100
    print(name)

Ключевое слово global позволяет вместо этого манипулировать идентификатором так, как если бы вы находились в более узкой области, позволяя переназначить глобальное имя другой ссылке:

def h():
    global name
    name = 100

h()
print(name) # 100

Однако, когда Вы используете ссылку для создания другой ссылки, между этими двумя ссылками нет связи. Таким образом,

name = 5
l = [name]

оставляет нам две ссылки на значение 5: одну из идентификатора name и одну из первой позиции l. Важно отметить, что эти две ссылки не связаны; мы можем изменить одно без изменения другого.

name = 6
print(l)  # [5]

Один из способов достижения sh того, что вы хотите - это использовать коробочный тип. Это означает, что вы создаете объект, который указывает на другой объект. Все ваши ссылки могут затем указывать на первый объект (блок), и вы можете свободно изменять то, на что он указывает (объект «внутри» блока), путем обновления только одной ссылки:

class Box:
    def __init__(self, value):
        self.value = value

box = Box(5)
l = [box]
box.value = 10
print(l[0].value)  # 10
0 голосов
/ 27 января 2020

Если вы считаете, что вам нужно это сделать, в вашем коде есть недостаток дизайна. Я действительно не рекомендовал бы делать это.

global_a = 5

def add_to_global(key, value):
    globals()[key] += value

add_to_global("global_a", 2)
print(global_a)

Вывод:

7
...