Например,

def function(data=None):
    print(data,id(data))
    if data is None:
        data=[]
    print(data,id(data))

    data.append(1)
    print("==================")

function()
function()

>> None 1781798096
[] 1780266168520
==================
None 1781798096
[] 1780266174856
==================

При первом выполнении function() переменная data ссылается на объект «None» (id: 1781798096). В третьей строке кода теперь data ссылается на пустой объект списка (id . "объект.

Но если мы изменим параметр по умолчанию на некоторый произвольный список, скажем, [0],

[0] 1780266149960
[0] 1780266149960
==================
[0, 1] 1780266149960
[0, 1] 1780266149960
==================

Мы обнаруживаем, что он дает идентичные значения идентификаторов.

Поэтому мой вопрос: почему мы не можем изменить переменную, которая ранее ссылалась на объект «None», и почему возникает такая разница, если мы устанавливаем параметр по умолчанию «None» и [0]?

-4
Jin 26 Авг 2017 в 10:10

3 ответа

Лучший ответ

Если вы спрашиваете, почему data значение id изначально одинаково, то это потому, что аргумент по умолчанию инициализируется один раз при определении функции и остается в программе. Это также причина для «Наименьшего удивления» и изменяемого аргумента по умолчанию .

Когда data переназначается, все, что происходит, это то, что он указывает на новый объект (пустой список), и этот объект может иметь или не иметь одинаковый id (сеансы REPL часто используют одно и то же {{ X2}} переменных, собираемых мусором).

3
cs95 26 Авг 2017 в 07:18

Вы вызываете функцию без аргумента, поэтому она устанавливается в None при вводе function(). Если вы хотите сохранить значения data, вам нужно вернуть переменную data, а затем передать ее function() во втором вызове.

0
Juergen 26 Авг 2017 в 07:47

None не является одноэлементным объектом, поэтому не следует создавать несколько объектов NoneType. (Обратите внимание, что вы можете создать несколько объектов одноэлементного класса). В python вы не всегда изменяете значение, которое оно содержит, вы вызываете метод для объекта, изменяете его или создаете новый объект и присваиваете ссылку на переменную. Ранее он содержал ссылку на объект None, когда вы меняли его, он содержал ссылку на другой объект. То же самое, когда вы снова присвоили None, Python инициализировал ссылочное значение со ссылкой None.

0
NishanthSpShetty 26 Авг 2017 в 07:23