Вопрос

Почему CPYPHON (не подсказка о других реализациях Python) имеет следующее поведение?

tuple1 = ()
tuple2 = ()                                                                                                   
dict1 = {}
dict2 = {}
list1 = []
list2 = []
# makes sense, tuples are immutable
assert(id(tuple1) == id(tuple2))
# also makes sense dicts are mutable
assert(id(dict1) != id(dict2))
# lists are mutable too
assert(id(list1) != id(list2))
assert(id(()) == id(()))
# why no assertion error on this?
assert(id({}) == id({}))
# or this?
assert(id([]) == id([]))

У меня есть несколько идей, почему это мая, но не могу найти конкретный Причина, почему.

РЕДАКТИРОВАТЬ

Для дальнейшего доказать точку Гленна и Томаса:

[1] id([])
4330909912
[2] x = []
[3] id(x)
4330909912
[4] id([])
4334243440
Это было полезно?

Решение

CPYPHON - это мусорные объекты сбора мусора, как только они выходят из прицела, поэтому второй [] создается после первого [] собирается. Итак, большую часть времени он заканчивается в том же месте памяти.

Это показывает, что происходит очень четко (вывод, скорее всего, будет отличаться в других реализациях Python):

class A(object):
    def __init__(self): print "a",
    def __del__(self): print "b",

# a a b b False
print A() is A()
# a b a b True
print id(A()) == id(A())

Другие советы

Когда вы называете id({}), Python создает дикт и передает его id функция. То id Функция принимает свой идентификатор (местоположение памяти) и выбрасывает Dict. Дикт-дикт разрушен. Когда вы делаете это дважды в быстрой последовательности (без каких-либо других диктопов, созданных в среднем времени), Dict Python создает второй раз, чтобы использовать один и тот же блок памяти, как первый раз. (Распределитель памяти Cpython делает это намного более вероятным, чем звучит.) С (в CPYthon) id Использует местоположение памяти в качестве идентификатора объекта, идентификатор двух объектов одинаковы. Это, очевидно, не происходит, если вы назначаете Dict для переменной, а затем получить его id(), потому что диктовы живы в то же время, Итак, их id должен быть другим.

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

Короче говоря, идентификатор объекта только уникален на всю жизнь объекта. Отказ После уничтожения объекта или до того, как он будет создан, что-то еще может иметь тот же идентификатор.

Это не работает так же в Jython ...

>>> id({})
1
>>> id([])
2

Может ли быть оптимизацию, на которой происходит широко используется (то есть пустые) контейнеры «интернированы», чтобы сохранить распределение распределения?

Это (в CPYthon) предлагает не:

>>> def mutateid(obj):
...   obj.append('x')
...   print obj
...   print id(obj)
... 
>>> mutateid([])
['x']
4299590472
>>> id([])
4299590472
>>> 

Оператор == в списках и диктовых дикторах не сравнивает идентификаторы объектов, чтобы увидеть, если они один и тот же объект - использование obj1 is obj2 для этого.

Вместо этого оператор == сравнивает членов списка DICT, чтобы увидеть, одинаковы ли они.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top