Идентификационные данные Python: разупорядочение Разносторонне развитой личности, уменьшение кода потребности [дубликат]

10
задан Community 23 May 2017 в 12:26
поделиться

5 ответов

Ваш четвертый вопрос, "в приведенном выше примере, два и ii указывают на ячейку памяти со значением 2, что было бы крайне странно", на самом деле является ключом к пониманию всего этого.

Если вы знакомы с такими языками, как C, то "переменные" на питоновском языке на самом деле работают не так, как раньше. В объявлении переменных Си типа:

int j=1;
int k=2;
k += j;

сказано: "Компилятор, зарезервируйте для меня две области памяти, на стеке, в каждой из которых достаточно места, чтобы вместить целое число, и запомните одну как 'j', а другую как 'k'". Затем заполните j значением '1', а k значением '2'.". Во время выполнения код говорит: "Возьмите целое содержимое k, добавьте целое содержимое j и сохраните результат обратно в k"

Казалось бы, эквивалентный код на Python:

j = 1
k = 2
k += j

говорит что-то другое: "Python, поищите объект, известный как "1", и создайте метку с именем "j", которая указывает на него"

. Найдите объект, известный как "2", и создайте метку под названием "k", которая указывает на него. Теперь посмотрите вверх на объект, на который указывает 'k' ('2'), посмотрите вверх на объект, на который указывает 'j' ('1'), и на объект, на который указывает 'k' в результате выполнения операции 'add' над двумя"

Разборка этого кода (с модулем dis) показывает, что это хорошо:

  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (j)

  3           6 LOAD_CONST               1 (2)
              9 STORE_FAST               1 (k)

  4          12 LOAD_FAST                1 (k)
             15 LOAD_FAST                0 (j)
             18 INPLACE_ADD
             19 STORE_FAST               1 (k)

Так что да, Python "переменные" - это метки , которые указывают на объекты, а не контейнеры , которые могут быть заполнены данными.

Остальные три вопроса - это все вариации на тему "когда Python создает новый объект из части кода, и когда он повторно использует тот, который у него уже есть". Последнее называется "interning"; это происходит с меньшими целыми числами и строками, которые выглядят (для Python) так, как будто это могут быть имена символов.

4
ответ дан 3 December 2019 в 16:52
поделиться

Каждая реализация Python полностью разрешена оптимизировать в любой степени (в том числе ... нет вообще ;-) Идентичность и распределение ImmyTable объектов (таких как цифры, кортежи и строки) [ [Никакая такая широта существует для изменяемых объектов , таких как списки, диктографические и наборы]].

между двумя неизменными ссылками объекта A и B , вся реализация должна гарантировать:

  1. ID (A) == ID (B) , aka A IS B , должен всегда подразумевать A == B
  2. и, следовательно, A! = B должен всегда подразумевать ID (A)! = ID (B) aka A - это не B

Примечание, в частности, есть NO ограничения , даже для неизменных типов, что A == B должен подразумевать это b (т.е. это ID (A) == ID (B) ). Только NOTE не делает эту гарантию (так что вы всегда можете проверить , если x None: , а не , если x == none: ).

Текущие реализации CPYPHON используют преимущества этих степеней свободы с помощью «объединения» (имеющие одно распределение, при этом единый ID , для) небольших целых чисел в определенном диапазоне, а также встроенный неизменен. Объекты, литералы которых появляются более одного раза в данной функции (например, если ваша функция F имеет четыре вхождения литерала «FOOBAR» , они все будут ссылаться на один экземпляр строки «FOOBAR» в константах функции, сохраняя небольшое пространство по сравнению с допустимой реализацией, которая будет хранить четыре одинаковых, но отдельные копии этой постоянной).

Все эти соображения реализации имеют довольно незначительный интерес для кодеров Python (если вы не работаете над внедрением Python, или, по крайней мере, то, что тесно связано с определенной реализацией, такими как система отладки).

8
ответ дан 3 December 2019 в 16:52
поделиться

Вы должны быть очень осторожны с подобными расследованиями. Вы изучаете внутреннюю сторону реализации языка, и это не гарантируется. Справка по id является spot-on: число будет разным для двух разных объектов, и одинаковым для одного и того же объекта. В качестве реализации в CPython это адрес памяти объекта. CPython может решить изменить эту деталь в любое время.

Детали маленьких целых чисел, интернированных в одно и то же время выделения, также являются деталями, которые могут измениться в любое время.

Также, если вы переключитесь с CPython на Jython, или PyPy, или IronPython, все ставки будут выключены, кроме документации по id().

2
ответ дан 3 December 2019 в 16:52
поделиться

Не каждый номер является уникальным объектом, и тот факт, что некоторые являются оптимизацией деталей интерпретатора Cpython. НЕ полагаться на это поведение. В этом отношении никогда не используйте для проверки на равенство. Используйте только , если вы абсолютно уверены, что вам нужен тот же объект.

1
ответ дан 3 December 2019 в 16:52
поделиться

Целые числа от -1 до 255 (?), А также строковые литералы интернируются. Каждый экземпляр в источнике фактически представляет один и тот же объект.

В CPython результатом id () является адрес в пространстве процесса PyObject.

9
ответ дан 3 December 2019 в 16:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: