причудливое поведение локальной переменной python - PullRequest
0 голосов
/ 04 января 2011

Могут ли эксперты по Python объяснить мне следующий вывод?

def modify_dict(exclude_params):
    exclude_params["domain_url"] = set()

def g(exclude_params={}):
    print id(exclude_params)
    print exclude_params
    modify_dict(exclude_params)
    print exclude_params
    return None

>>> g()
23191104
{}
{'domain_url': set([])}
>>> g()
23191104
{'domain_url': set([])}
{'domain_url': set([])}
>>>

Я не передавал аргументы g ни в одном вызове, поэтому локальная переменная exclude_params должна быть инициализирована {}.Но во втором вызове это не так.

Даже странно, что адреса локальных переменных одинаковы в двух отдельных вызовах.Итак, старая локальная переменная используется повторно ?? !!!

Ответы [ 2 ]

12 голосов
/ 04 января 2011

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

def foo(some_dict=None):
  if some_dict is None:
    some_dict = {}

Это потому, что:

def foo(arg={})

- это инструкция, как и любая другая, что означает, что {} создается именно в этом месте и выполняетсятолько один раз.

0 голосов
/ 04 января 2011

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

Чтобы пояснить еще кое-что, определение функции выполняется, когда функция определена , а не когда она вызывается. Таким образом, параметр some_dict также будет установлен в словарь при определении функции, а не при ее вызове, поскольку это является частью определения функции.

По крайней мере, мне так полезно об этом думать.

...