2012-06-15 2 views
1

У меня есть функция, которая неоднократно индексируется в словарь с тем же ключом. Можно ли взять ссылку на рассматриваемый предмет?Можно ли взять ссылку на элемент словаря в Python?

def my_function(self, event): 
    self.__observers[event] ... #this is get is performed multiple times 
    observer_ref = self.__observers[event] #can I make this a reference to the value? 

Update: Цель состоит в том, чтобы не сделать копию того, что у себя .__ наблюдателей [событий]. Я ищу поведение, похожее на C++, например.

int x = 1 
int& y = x #reference to y, not a copy 
+0

Это зависит от того, что вы считаете «ссылкой». Все назначения создают ссылку. – geoffspear

+0

Нет, см. Http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference –

+0

Для хорошей статьи о шаблоне наблюдателя в Python, http: // radio -weblogs.com/0124960/2004/06/15.html –

ответ

3

Когда вы присваиваете значение имени (переменной) в Python, переменная является просто ссылкой на значение.

Так, например, говорят self.__observers[event] начинается как пустой список, следующий код будет работать нормально:

assert self.__observers[event] == [] 
observer_ref = self.__observers[event] 
observer_ref.append(1)     # this modifies self.__observers[event] 
assert self.__observers[event] == [1] 

Однако, как отметил BrenBarn, если вы должны были затем присвоить observer_ref новое значение, оно будет не изменять self.__observers[event].

0

Конечно. Почему бы вам не попробовать и не посмотреть?

Как указано в комментарии, это зависит от того, что вы подразумеваете под «ссылкой». Если вы делаете то, что вы предлагаете, назначение вашей новой переменной не изменит dict.

>>> d = {'a': 1} 
>>> d['a'] 
1 
>>> x = d['a'] 
>>> x 
1 
>>> x = 2 
>>> d 
{u'a': 1} 
0

Это действительно зависит от того, что вы подразумеваете под «ссылкой». ... и это также зависит от того, что вы собираетесь делать со ссылкой. например.

class Test(object): 
    def __init__(self): 
     self.__observers = {'event1': {'test':'this'}, 'event2': {'test':'that'}} 

    def get_observers(self): 
     return self.__observers 

    def my_function(self, event): 
     observer_ref = self.__observers[event] 
     return observer_ref 

if __name__ == '__main__': 
    t = Test() 

    my_event = 'event1' 

    print('From class: {}'.format(t.get_observers()[my_event])) 
    my_ref = t.my_function(my_event) 
    print('From my_function: {}'.format(my_ref)) 

    my_ref['something'] = 'else' 

    print('From my_function after addition: {}'.format(my_ref)) 
    print('From class after addition: {}'.format(t.get_observers()[my_event])) 

    my_ref = 'something else entirely' 

    print('From my_function after re-assignment: {}'.format(my_ref)) 
    print('From class after re-assignment: {}'.format(t.get_observers()[my_event])) 

Результаты в:

From class: {'test': 'this'} 
From my_function: {'test': 'this'} 
From my_function after addition: {'test': 'this', 'something': 'else'} 
From class after addition: {'test': 'this', 'something': 'else'} 
From my_function after re-assignment: something else entirely 
From class after re-assignment: {'test': 'this', 'something': 'else'} 

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

Смежные вопросы