validar solo regulares python3 para metacaracter letras fechas expresiones ejemplos python iterable

solo - validar expresiones regulares en python



¿Por qué los objetos de coincidencia de expresiones regulares no son iterables aunque implementan__getitem__? (1)

Como sabrá, la implementación de un método __getitem__ hace que una clase sea iterable :

class IterableDemo: def __getitem__(self, index): if index > 3: raise IndexError return index demo = IterableDemo() print(demo[2]) # 2 print(list(demo)) # [0, 1, 2, 3] print(hasattr(demo, ''__iter__'')) # False

Sin embargo, esto no es cierto para los objetos de coincidencia de expresiones regulares:

>>> import re >>> match = re.match(''(ab)c'', ''abc'') >>> match[0] ''abc'' >>> match[1] ''ab'' >>> list(match) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ''_sre.SRE_Match'' object is not iterable

Vale la pena señalar que esta excepción no se produce en el método __iter__ , porque ese método ni siquiera se implementa:

>>> hasattr(match, ''__iter__'') False

Entonces, ¿cómo es posible implementar __getitem__ sin hacer que la clase sea iterable?


Hay mentiras, malditas mentiras y luego está la documentación de Python.

Tener __getitem__ para una clase implementada en C no es suficiente para que sea iterable. Esto se debe a que en realidad hay 2 lugares en el PyTypeObject donde el __getitem__ se puede asignar a: tp_as_sequence y tp_as_mapping . Ambos tienen una ranura para __getitem__ ( [1] , [2] ).

Mirando la fuente de SRE_Match , tp_as_sequence se inicializa a NULL mientras que tp_as_mapping está definido.

La función incorporada iter() , si se llama con un argumento, llamará a PyObject_GetIter , que tiene el siguiente código:

f = t->tp_iter; if (f == NULL) { if (PySequence_Check(o)) return PySeqIter_New(o); return type_error("''%.200s'' object is not iterable", o); }

Primero verifica la ranura tp_iter (obviamente NULL para los objetos _SRE_Match ); y en su defecto, entonces si PySequence_Check devuelve true, un nuevo iterador de secuencia, de lo contrario, se TypeError un TypeError .

PySequenceCheck primero verifica si el objeto es un dict o una subclase de dict , y en ese caso devuelve false. De lo contrario, devuelve el valor de

s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL;

y como s->ob_type->tp_as_sequence era NULL para una instancia _SRE_Match , se devolverá 0, y PyObject_GetIter genera TypeError: ''_sre.SRE_Match'' object is not iterable .