Si un objeto no tiene una __contains__
implementación, in
recurre a un valor predeterminado que básicamente funciona así:
def default__contains__(self, element):
for thing in self:
if thing == element:
return True
return False
Y si un objeto no tiene una __iter__
implementación, for
recurre a un valor predeterminado que básicamente funciona así:
def default__iter__(self):
i = 0
try:
while True:
yield self[i]
i += 1
except IndexError:
pass
Estos valores predeterminados se utilizan incluso si el objeto no pretende ser una secuencia.
Su 1 in f
y las 5 in f
pruebas están utilizando los retrocesos predeterminados para in
y for
, lo que lleva al comportamiento observado. 1 in f
encuentra de 1
inmediato, pero __getitem__
nunca regresa 5
, por lo que 5 in f
corre para siempre.
(Bueno, en realidad, en la implementación de referencia de Python, la __iter__
reserva predeterminada almacena el índice en una variable de nivel C de tipo Py_ssize_t
, por lo que si espera lo suficiente, esa variable se maximiza y Python genera un OverflowError . Si vio eso, usted debe estar en una compilación de Python de 32 bits. Las computadoras no han existido lo suficiente como para que alguien pueda acceder a eso en una Python de 64 bits).
for
yin
, anterior a la introducción de__iter__
y__contains__
. Consulte la documentación de Python 1.4 aquí y aquí .