2015-09-01 3 views
0

Я читал учебник python из Документации по выпуску Python 2.7.10, и я наткнулся на что-то вроде этого.Python Default Arguments Evaluation

Код

def fun1(a,L=[]): 
    L.append(a) 
    return L 

print fun1(1) 
print fun1(2) 
print fun1(3) 

def fun2(a,L = None): 
    if L is None: 
     L=[] 
    L.append(a) 
    return L 

print fun2(1) 
print fun2(2) 
print fun2(3) 

Выход

[1] 
[1, 2] 
[1, 2, 3] 
[1] 
[2] 
[3] 

Process finished with exit code 0 

Если L=[] в первой функции fun1() становится вызывается только один раз, выход fun1() нормально. Но тогда почему L=None получает вызов каждый раз в fun2().

+0

* «почему' L = None' не вызывается каждый раз »* - Я не знаю, что вы пытаетесь сказать с этим. – deceze

+0

Я предполагаю, что 'L = None' получает вызов/выполняется каждый раз. Вот почему условие 'if L is None 'истинно каждый раз во второй функции fun2()'. – psychoCoder

+1

По умолчанию аргументы оцениваются по объявлению функции.Пустой список изменен, поэтому в каждом вызове функции вы редактируете тот же список. При добавлении к нему не создается новый объект. С None, список создается в теле функции. Каждый раз, когда возвращается новый список из функции. –

ответ

1

При определении функции значения аргументов по умолчанию получить оценку, но тела функции только компилируются. Вы можете проверить результат определения функции через атрибуты. Theres a __defaults__ атрибут, содержащий значения по умолчанию и атрибут __code__, содержащий тело (поэтому они создаются, когда функция определена).

Что происходит во втором примере, что None действительно получить оценку по определению (это имеет значение None дух!), Но код, который условно присваивает [] к L только компилируется и запускается каждый раз, когда (условие проходит).

1

аргументы по умолчанию оцениваются только один раз. В fun1 у вас есть тот же список, который вы продолжаете добавлять. В fun2 вы назначаете новый параметр [] и затем добавляете к нему. Как и любой уступки, его объем будет ограничен блоком оно произошло в.

2

L=[] в объявлении функции делает Python в основном это сделать:

  • эта функция имеет параметр с именем L
  • его по умолчанию аргумент [], давайте установим этот конкретный [] в сторону и использовать его в любое время нет параметра передан для L
  • каждый раз, когда вызывается функция, создайте переменную L и назначьте ей либо переданный параметр, либо значение, которое мы отложили ранее

Итак, часть [] выполняется один раз, что создает объект списка, который откладывается и хранится вокруг, поэтому он корректирует изменения, если вы его изменяете. Точно так же происходит с None, однако None не изменяется и не изменяет его, поэтому вы не видите каких-либо странных побочных эффектов. None по-прежнему только «исполняется» один раз, и то значение None выделяется так же, как и список, просто вы ничего не делаете с самим значением None.

+0

Но я меняю 'L = None' на' L = [] 'внутри условия' if 'в' fun2() '. Почему это назначение/изменение не является постоянным или видимым для других последующих вызовов функций. – psychoCoder

+0

Снова: * каждый раз, когда вызывается функция, создается __variable__ 'L' и присваивается значение *. *** Значение '[]' *** является постоянным, а не его ассоциацией с 'L'. *** Значение '[]' *** хранит вещи, которые вы '.append', а не' L'. Постоянный объект '[]' в памяти отличается от переменной 'L', указывающей на нее. – deceze