Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Sacar la basura trae sus problemas

Es­to no de­be­ría sor­pren­der­te:

>>> a = [1,2]
>>> b = [3,4]
>>> a is b
False
>>> a == b
False
>>> id(a) == id(b)
False

Des­pués de to­do, a y b son co­sas dis­tin­ta­s. Sin em­bar­go:

>>> [1,2] is [3,4]
False
>>> [1,2] == [3,4]
False
>>> id([1,2]) == id([3,4])
True

Re­sul­ta que si uno usa li­te­ra­le­s, una de esas co­sas no es co­mo las de­má­s.

Pri­me­ro la ex­pli­ca­ció­n. Cuan­do uno no tie­ne más re­fe­ren­cias a un da­to, va a ser "gar­ba­ge co­llec­te­d", la me­mo­ria se li­be­ra pa­ra que se pue­da usar pa­ra otra co­sa.

En el primer caso, las variables a y b guardan referencia a las listas. Es decir que tienen que existir todo el tiempo, ya que yo podría decir print a y python tiene que poder responderme con el valor de a.

En el segundo caso, uso literales, lo que quiere decir que no hay referencias a las listas después de que se usan. Cuando python evalúa id([1,2]) == id([3,4]) evalúa primero el lado izquierdo del ==. Después de que termina con eso, no hace falta mantener el [1,2] a mano, así que se borra. Entonces, al evaluar el lado derecho, crea [3,4].

Por pura casualidad, lo pone en exactamente el mismo lugar en que estaba el [1,2], asi que id devuelve el mismo valor. Esto sirve para recordar dos cosas:

  1. a is b es usual­men­te (pe­ro no siem­pre) equi­va­len­te a id(a) == id(­b)

  2. La re­­co­­­le­c­­ción de ba­­su­­ra tie­­ne efe­c­­tos se­­cun­­da­­rios que en una de esas no es­­pe­­ra­­ba­s.

David / 2012-01-31 22:39:

Yes, but it's not pure chance - it's the result of object pooling in the implementation. If it were pure chance, the situation you describe would indeed be very rare.

Roberto Alsina / 2012-01-31 22:47:

Well, it's pure chance in that, for example, no other thread allocated the memory, and that python uses this specific memory allocation strategy. So, it's not pure chance that it happens this time, but it is pure chance that it happens at all.

Facundo Batista / 2012-02-03 12:34:

It's worthy to note that this behaviour is an implementation detail: it's not enforced by the Python (the language) specification, so in other Python implementations (PyPy, Jython, IronPython) you may get different results.


Contents © 2000-2020 Roberto Alsina