Как сделать ссылку на Ints по имени в Python - PullRequest
4 голосов
/ 04 октября 2010

Я хочу иметь ссылку, которая читается как "любая переменная имени, на которую указывает 'x'" с целочисленными значениями, так что она ведет себя как:

>>> a = 1
>>> b = 2
>>> c = (a, b)
>>> c
(1, 2)
>>> a = 3
>>> c
(3, 2)

Я знаю, что могу сделать что-то подобное со списками, выполнив:

>>> a = [1]
>>> b = [2]
>>> c = (a, b)
>>> c
([1], [2])
>>> a[0] = 3
>>> c
([3], [2])

, но это может быть легко потеряно, если назначить a или b чему-то, а не их элементам.

Есть ли простой способ сделать это?

Ответы [ 6 ]

4 голосов
/ 04 октября 2010

Нет, в Python нет прямого способа сделать это.Причина в том, что и скалярные значения (числа), и кортежи неизменны .Как только вы установили привязку имени к неизменяемому значению (например, имя c с кортежем (1, 2)), ничто из того, что вы делаете, кроме переназначения c, не может изменить значение, с которым оно связано.

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

2 голосов
/ 04 октября 2010

Если вам просто нужно, чтобы текущие значения были помещены в кортеж на лету, вы можете использовать лямбду.Вам придется позвонить с, а не просто вернуть или использовать его, но это может быть приемлемо в вашей ситуации.Как то так:

>>> a = 1
>>> b = 2
>>> c = lambda: (a, b)
>>> c()
(1, 2)
>>> a = 3
>>> c()
(3, 2)
2 голосов
/ 04 октября 2010

Какое бы возможное решение вы ни выбрали во второй последней строке, оно всегда уничтожит его:

a = 3

Это назначит переменной совершенно новый контент.Если a не обозначает свойство объекта или чего-либо (или ключ в списке, как вы делали в своем собственном примере), вы не сможете установить связь между первым и последним a.

1 голос
/ 04 октября 2010
class ByRefValue(object):
    def __init__(self, value):
        self.value = value

Передайте его куда угодно, помня, что вам нужен доступ к элементу value, а не ко всему объекту.


В качестве альтернативы, globals().get('a', 0) вернет значение a если он находится в глобальном пространстве имен (или ноль, если это не так).


Наконец:

import threading
tls = threading.local()

tls.a = 1

Если вы импортируете tls в каждый модуль, где выЕсли вам это нужно, вы получите одно и то же значение для a в каждом потоке .В зависимости от настройки вашей программы это может быть приемлемо, идеально или бесполезно.

1 голос
/ 04 октября 2010

В Python нет пути не только потому, что числа неизменны, но и потому, что у вас нет указателей. Включение значения в список имитирует наличие указателей, поэтому это лучшее, что вы можете сделать.

0 голосов
/ 04 октября 2010

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

...