Что происходит, когда я создаю список, такой как c=[1] в python, с точки зрения привязки объекта имени?
После прочтения http://www.effbot.org/zone/python-objects.htm я остаюсь с этим вопросом:
В питоне, если a=1
создает целочисленный объект и связывает его с именем a
, b=[]
создает пустой список-объект и привязывает его к имени b
что происходит, когда я звоню, например c=[1]
?
Я предполагаю, что это создает список объектов и связывает его с именем c
, но как 1
точнее? Как выглядит фактическое содержимое объекта list под капотом? Он состоит из целочисленного объекта или ссылки на "отдельный" целочисленный объект? Это нормально думать, например, c[0]
как имя привязано к элементу списка?
А как насчет следующего:
d=1 # creates int(1)-object and binds it to d
e=[d] # creates list-object and binds it to e, but what happens with d?
Будет ли содержимое списка-объекта (по имени e
) быть ссылкой на целочисленный объект с именем d
или новый целочисленный объект?
Я полагаю, что ответ заключается в этой цитате мистера Лунда из вышеупомянутого источника, но я все еще немного растерялся:
Затем вы вызываете метод для этого объекта, говоря ему добавить целочисленный объект к себе. Это изменяет содержимое объекта списка, но не затрагивает пространство имен и не затрагивает целочисленный объект.
Также я считаю, что часть ответа находится здесь: Python; привязки имен не являются ссылками на объекты?, но я все еще ищу более глубокое понимание.
1 ответ
В питоне, если
a=1
создает целочисленный объект и связывает его с именем a,b=[]
создает пустой объект списка и связывает его с именем b, что происходит, когда я звоню, например,c=[1]
?
Когда вы назначаете c
в [1]
вы говорите Python о создании объекта списка с указателем на целочисленный объект, который имеет значение 1
, Это можно увидеть, посмотрев, как объекты списка представлены в C под капотом:
typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
Как видно из приведенного выше примера, ob_item
представляет собой последовательность указателей, где каждый указатель указывает на PyObject
в памяти. В твоем случае, ob_item
содержит указатель, который указывает на целочисленный объект 1
,
Можно ли думать, например, о c[0] как об имени, связанном с элементом списка?
На самом деле, нет. когда вы делаете c[0]
вы говорите Python, чтобы он возвращал указатель на объект по индексу 0
, Это снова можно наблюдать, посмотрев, что происходит, когда мы индексируем объект списка на уровне C:
Py_INCREF(a->ob_item[i]);
return a->ob_item[i];
А как насчет следующего:
d=1 # creates int(1)-object and binds it to d e=[d] # creates list-object and binds it to e, but what happens with d?
В приведенном выше примере переменная d
псевдоним объекта 1
, а также e
содержит указатель на объект 1
, И то и другое d
а также e[0]
указать на тот же объект, однако:
>>> a = 10
>>> b = [a]
>>> id(a) == id(b[0])
True
>>>
Когда ты сделал e = [d]
вы говорите Python, чтобы построить список, который содержит указатель на объект, который d
ссылается.