2010-06-01 2 views
1

Foo = "Foo" Защиту бар (Foo): Foo = "бар"Python аргумент функции сфера (Словари v Строки.)

bar(foo) 
print foo 

# foo is still "foo"... 

foo = {'foo':"foo"} 
def bar(foo): 
    foo['foo'] = "bar" 

bar(foo) 
print foo['foo'] 

# foo['foo'] is now "bar"? 

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

Спасибо!

ответ

3

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

Причина в том, что при передаче словаря во вторую функцию bar Python передает только ссылку на словарь. Поэтому, когда вы изменяете его внутри функции, вы изменяете тот же объект, который существует вне функции. С другой стороны, в первой функции bar вы назначаете другой объект имени foo внутри функции при записи foo = "bar". Когда вы это сделаете, имя foo внутри функции начнет ссылаться на строку "bar", а не на строку "foo". Вы изменили, к какому объекту относится это имя. Но внутри функции функция foo и foo - это разные имена, поэтому, если вы измените объект, помеченный foo внутри функции, вы не будете влиять на имя foo вне функции. Поэтому они ссылаются на разные объекты.

+0

Справедливо. Я надеялся, что будет что-то вроде ключевого слова const, чтобы сделать это немного приятнее. Большое спасибо! –

+0

Это то место, где я бы сделал бесстыдный плагин для изучения C++. Половина подобных недоразумений на языках высокого уровня объясняется отсутствием понимания того, как работают языки. Если вы потратите время на изучение немного C++, вы начнете обнаруживать, что выделение таких вещей на Python - это то, что они есть, потому что они являются: a) самой быстрой или b) самой простой реализацией. Вам не нужно знать C++, чтобы понять, как работает Python, но это упрощает работу. –

+0

@Shaun: ничто на самом деле не является постоянным в Python (кроме имен ключевых слов, таких как 'None',' True', 'False',' 1', '2' и т. Д.), И в любом случае ключевое слово' const' не помогло бы вы здесь, потому что ваш второй 'bar()' выполняет операцию над объектом с именем 'foo', не изменяя названия. 'const 'предотвращает последнее, но не первое. Тимоти хорошо понимает, что изучение C++ (или C), вероятно, поможет сделать это более ясным. –

1

Аргументы передаются по значению, но в этом случае это значение является ссылкой на объект. Это также называется call by sharing. Так что да, если вам нужен новый словарь, вам нужно будет создать его в функции.

0

Я хотел бы добавить, что

temp_dict = CONSTdict 

не помогло, так как это просто копирует указатель.

Вместо этого мне нужно было:

temp_dict = dict(CONSTdict) 

Cheers,

Shaun

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