Можно ли дать формальное определение термину «значение объекта» в CPython? После краткого прочтения некоторых справочных статей и руководств по Python я пришел к выводу, что в большинстве случаев этот термин означает одну из следующих двух вещей (в зависимости от контекста). Верен ли этот вывод или нет?
В широком смысле «значение объекта» означает все данные, хранящиеся в структуре объекта (эта структура является производной от структуры PyObject), за исключением обозначения типа и счетчика ссылок. Другими словами, это данные (набор байтов), хранящиеся в полях структуры объекта, за исключением полей ob_type
и ob_refcnt
(и, возможно, некоторых других полей бухгалтерского учета, связанных со сборкой мусора). Похоже, что переменные экземпляра объекта Python также хранятся в этой структуре. Однако я не уверен насчет связанных методов – где они хранятся после создания.
Например, каждый объект типа int
генерируется следующей структурой (после раскрытия макроса C):
struct _longobject {
Py_ssize_t ob_refcnt; /* object reference counter */
PyTypeObject* ob_type; /* object type designator*/
Py_ssize_t ob_size;
digit ob_digit[1];
};
Следовательно, его значением являются данные (набор байтов), хранящиеся в ob_size
и ob_digit[1]
.
В узком смысле «значение объекта» означает строковое представление объекта, которое оценивается либо obj.__repr__()
, либо obj.__str__()
. Это представление обычно не сохраняется явно в структуре PyObject, но оценивается вышеупомянутыми связанными методами, которые во время этой оценки используют несколько полей структуры PyObject. Обратите внимание, что для объектов некоторых типов (например, объектов-функций или файловых объектов) такое строковое представление тривиально и не содержит никакой ценной информации.
Официальная ссылка на Python не содержит определения значения объекта. Это просто говорит, что
Каждый объект имеет идентификатор, тип и значение.
В глоссарии Python тоже нет такого определения (хотя термин «значение» встречается в нем 34 раза). Более того, не совсем ясно, как нам следует интерпретировать термин «ценность» в его определении объекта:
Объект — любые данные с состоянием (атрибутами или значением) и определенным поведением (методами).
В этом определении «ценность» противопоставляется «атрибутам». Возможно, нам следует интерпретировать здесь «ценность» в узком смысле, как я определил ее выше, но я не уверен.
Ответ ниже является хорошим объяснением концепции «значения» в Python. Я думаю, что определение, написанное в моем первом пункте, можно назвать определением «представления значения объекта в памяти» (синоним: «байтовое представление значения объекта»). Это представление не является уникальным, поскольку оно зависит от машины. А определение, написанное во втором пункте, следует называть определением «строкового представления объекта» (синоним: «строковое представление значения объекта»).
@MichaelButscher Меня смутило то, что они написали «состояние (атрибуты или значения)», а не «состояние (атрибуты или значения)». Возможно, это просто опечатка...
Ни одно из предложенных определений не подходит. Формального определения ценности объекта не существует. Это скорее неформальная, интуитивная концепция.
Самое близкое к определению значения объекта, которое мне было бы удобно, — это «информация, которую представляет объект». Например, информация, представленная объектом int 5
, — это число 5. Наборы {-1, -2}
и {-2, -1}
представляют одну и ту же информацию и имеют одинаковое значение. Это верно, даже если содержимое памяти, соответствующей этим объектам, не совпадает, и даже если они имеют разные строковые представления.
В документации по модели данных для операторов сравнения говорится:
Значение объекта — довольно абстрактное понятие в Python: например, не существует канонического метода доступа к значению объекта. Кроме того, нет требования, чтобы значение объекта было построено определенным образом, например. состоит из всех атрибутов данных. Операторы сравнения реализуют особое представление о значении объекта. Их можно рассматривать как определение значения объекта косвенно, посредством реализации сравнения.
Итак, это одно понятие ценности — объекты, которые сравниваются равными по ==
, имеют одинаковую ценность в соответствии с этим понятием стоимости. Но есть объекты с необычной реализацией сравнения. float('nan')
сравнивает неравным самому себе, так какова его ценность? А {1: 1, 2: 2}
и {2: 2, 1: 1}
сравниваются друг с другом, но содержат разную информацию о порядке. Следует ли считать порядок частью ценности диктата?
В конечном счете, команда разработчиков просто не пытается написать официальное, формальное определение «ценности» или пытается заставить концепцию «ценности» стать чем-то достаточно жестким, чтобы ее можно было определить. Это не решает практических проблем.
Какую информацию представляет объект функции? Можем ли мы сказать, что эта информация является «определением функции»?
Если объект Python не имеет значения, то этот объект не будет иметь значения, и поэтому его не следует хранить. Единственным таким объектом является None
, поэтому уже рекомендуется использовать if item is None:
, а не if item == None:
, поскольку любой такой элемент будет ссылкой на единственный экземпляр None.
Таким образом, value
элемента может быть любого типа, включая данные с более чем одним «значением», например, в комплексе, кортеже, списке, массиве и т. д., но в этих случаях, вероятно, каждый из нескольких элементов «значения» быть самостоятельным объектом.
Ваше первое «определение» - это скорее детали того, как это реализовано в настоящее время, и оно может не оставаться верным или быть верным в других реализациях, кроме cPython. Во-вторых, предполагается, что все «значения», связанные с объектом, всегда будут отображаться методами __str__
или __repr__
, что не обязательно соответствует действительности.
Для меня «ценность» — это информация, которую объект содержит, кроме той, которая необходима для его собственной реализации. Это также то, что делает этот объект стоящим.
Я бы понимал «состояние (атрибуты или значения)» как «состояние (называемое «атрибутами» или «значениями»)», следовательно, синонимы.