Я бы расширил версию Аарона Дигуллы. То, что он имеет сейчас, копируется здесь:
class DictRef(object):
def __init__(self, d, key): self.d, self.key = d, key
d = {}
d.update({
'key1': ['val1','val2'],
'key2': DictRef(d, 'key1')
})
Я предполагаю, что он хочет воспроизвести истинную ссылочную семантику, так что доступ к 'key2'
всегда даст вам возможность получить то, что 'key1'
имеет в качестве значения. проблема в том, что d['key1']
это list
, d['key2']
это DictRef
. Таким образом, чтобы получить «значение» 'key1'
, все что вам нужно сделать, это d['key1']
, но для 'key2'
вы должны сделать d[d['key2'].key]
. Кроме того, вы не можете иметь ссылку на ссылку, которая работает разумно, она станет d[d[d['key2'].key].key]
. И как вы различаете ссылку и обычное значение? Вероятно, через проверку типов с помощью isinstance (v, DictReference) ( ew ).
Так что у меня есть предложение исправить все это.
Лично я не понимаю, зачем нужна настоящая ссылочная семантика. Если они кажутся необходимыми, их можно сделать ненужными путем реструктуризации проблемы или решения проблемы. Может даже случиться так, что они никогда не были необходимы, и простой d.update(key2=d['key1'])
решил бы проблему.
В любом случае, к предложению:
class DictRef(object):
def __init__(self, d, key):
self.d = d
self.key = key
def value(self):
return self.d[self.key].value()
class DictVal(object):
def __init__(self, value):
self._value = value
def value(self):
return self._value
d = {}
d.update(
key1=DictVal(['val1', 'val2']),
key2=DictRef(d, 'key1')
)
Теперь, чтобы получить значение любого ключа , независимо от того, является ли это ссылкой или нет, нужно просто сделать d[k].value()
. Если есть ссылки на ссылки, они будут правильно разыменовываться в цепочке. Если они образуют очень длинную или бесконечную цепочку, Python завершится с ошибкой RuntimeError для чрезмерной рекурсии.