esto es con CPython 2.7.2 y 3.2.2.¿por qué algunas expresiones que hacen referencia a `` x.y`` cambian `` id (x.y) ``?
supongamos que definimos Class
y obj
de la siguiente manera.
class Class(object):
def m(self):
pass
@property
def p(self):
return None
@staticmethod
def s():
pass
obj = Class()
versión corta
¿por qué el siguiente código de salida para cada False
print()
?
print(Class.__dict__ is Class.__dict__)
print(Class.__subclasshook__ is Class.__subclasshook__)
print(Class.m is Class.m)
print(obj.__delattr__ is obj.__delattr__)
print(obj.__format__ is obj.__format__)
print(obj.__getattribute__ is obj.__getattribute__)
print(obj.__hash__ is obj.__hash__)
print(obj.__init__ is obj.__init__)
print(obj.__reduce__ is obj.__reduce__)
print(obj.__reduce_ex__ is obj.__reduce_ex__)
print(obj.__repr__ is obj.__repr__)
print(obj.__setattr__ is obj.__setattr__)
print(obj.__sizeof__ is obj.__sizeof__)
print(obj.__str__ is obj.__str__)
print(obj.__subclasshook__ is obj.__subclasshook__)
print(obj.m is obj.m)
(eso es en Python 2; para Python 3, omita el print()
para Class.m
y añadir otras similares para obj.__eq__
, obj.__ge__
, obj.__gt__
, obj.__le__
, obj.__lt__
y obj.__ne__
)
y por qué, por el contrario, ¿El siguiente código muestra True
para cada print()
?
print(Class.__class__ is Class.__class__)
print(Class.__delattr__ is Class.__delattr__)
print(Class.__doc__ is Class.__doc__)
print(Class.__format__ is Class.__format__)
print(Class.__getattribute__ is Class.__getattribute__)
print(Class.__hash__ is Class.__hash__)
print(Class.__init__ is Class.__init__)
print(Class.__module__ is Class.__module__)
print(Class.__new__ is Class.__new__)
print(Class.__reduce__ is Class.__reduce__)
print(Class.__reduce_ex__ is Class.__reduce_ex__)
print(Class.__repr__ is Class.__repr__)
print(Class.__setattr__ is Class.__setattr__)
print(Class.__sizeof__ is Class.__sizeof__)
print(Class.__str__ is Class.__str__)
print(Class.__weakref__ is Class.__weakref__)
print(Class.p is Class.p)
print(Class.s is Class.s)
print(obj.__class__ is obj.__class__)
print(obj.__dict__ is obj.__dict__)
print(obj.__doc__ is obj.__doc__)
print(obj.__module__ is obj.__module__)
print(obj.__new__ is obj.__new__)
print(obj.__weakref__ is obj.__weakref__)
print(obj.p is obj.p)
print(obj.s is obj.s)
(eso es en Python 2; para Python 3, añadir similares print()
s para Class.__eq__
, Class.__ge__
, Class.__gt__
, Class.__le__
, Class.__lt__
y Class.__ne__
y Class.m
)
versión larga
si solicite id(obj.m)
dos veces seguidas, luego obtenemos la misma identificación dos veces.
>>> id(obj.m)
139675714789856
>>> id(obj.m)
139675714789856
pero si nos preguntamos por id(obj.m)
, a continuación algunas expresiones que contienen referencias a obj.m
, a continuación, id(obj.m)
de nuevo, cambia el ID de veces (pero no siempre). si cambia, si pedimos id(obj.m)
en otro momento, la identificación cambia algunas veces al valor original (pero no siempre). si no cambia, parece que la repetición de las expresiones intermedias hace que la ID alternará entre los dos valores.
aquí son algunos ejemplos en los que id(obj.m)
no cambia:
>>> print(obj.m); id(obj.m)
<bound method Class.m of <__main__.Class object at 0x7f08c96058d0>>
139675714789856
>>> obj.m is None; id(obj.m)
False
139675714789856
>>> obj.m.__func__.__name__; id(obj.m)
'm'
139675714789856
>>> obj.m(); id(obj.m)
139675714789856
aquí es un ejemplo en el que id(obj.m)
cambios, a continuación, cambia de nuevo:
>>> obj.m; id(obj.m); id(obj.m)
<bound method Class.m of <__main__.Class object at 0x7f08c96058d0>>
139675715407536
139675714789856
aquí es un ejemplo en el que id(obj.m)
cambios, entonces no cambia de nuevo:
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675715407536
139675715407536
aquí es la misma expresión, que se repite un par de veces para demostrar el comportamiento alterna:
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675714789856
139675714789856
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675715407536
139675715407536
>>> obj.m is obj.m; id(obj.m); id(obj.m)
False
139675714789856
139675714789856
así toda mi pregunta es
- qué tipo de atributos podrían cambiar su identidad como un efecto secundario de las expresiones que no modifica esos atributos?
- ¿qué tipo de expresiones desencadenan dichos cambios?
- ¿Cuál es el mecanismo que causa dichos cambios?
- ¿bajo qué condiciones se reciclan las identidades pasadas?
- ¿por qué la primera identidad no se recicla indefinidamente, lo que evitaría toda esta complicación?
- ¿Está documentado todo esto?
La respuesta de @Kindall resuelve la mayor parte de mi pregunta, pero esto resuelve la subpregunta sobre las ID recicladas. gracias. – nisavid