2011-10-27 8 views
17

Estaba probando un código en el intérprete y noté un comportamiento inesperado para la clase sqlite3.Row.¿Cómo se puede imprimir un resultado de objeto diferente que str() y repr()?

Mi entendimiento es que print obj siempre obtendrá el mismo resultado que print str(obj), y escribiendo obj en el intérprete obtendrá el mismo resultado que print repr(obj), sin embargo este no es el caso para sqlite3.Row:

>>> print row  # the row object prints like a tuple 
(u'string',) 
>>> print str(row) # why wouldn't this match the output from above? 
<sqlite3.Row object at 0xa19a450> 

>>> row    # usually this would be the repr for an object 
(u'string',) 
>>> print repr(row) # but repr(row) is something different as well! 
<sqlite3.Row object at 0xa19a450> 

pienso sqlite3.Row debe ser una subclase de tuple, pero todavía no entiendo exactamente lo que ocurre detrás de escena que podría causar este comportamiento. ¿Alguien puede explicar esto?

Esto se probó en Python 2.5.1, no estoy seguro si el comportamiento es el mismo para otras versiones de Python.

No estoy seguro de si esto importa o no, pero el atributo row_factory para mi Connection se configuró en sqlite3.Row.

+0

¿Has visto http://stackoverflow.com/questions/1436703/difference-between-str-and-repr-in-python antes de publicar? – ktdrv

+0

@kaloyan - No puedo encontrar nada allí que responda a mi pregunta, si puede indicarlo. –

+0

Comportamiento interesante. 'sqlite3.Row' no parece subclasificar tupla, así que supongo que es la lista de impresión de casos especiales y/o tuplas basadas en algunos otros criterios aparte de la herencia, pero no encuentro nada en la documentación que admita, mucho menos explicar esto. – millimoose

Respuesta

11

PySqlite proporciona el gancho nativo especial para print, pero no implementa __repr__ o __str__. Diría que es una oportunidad perdida, pero al menos explica el comportamiento que estás observando.

ver fuente pysqlite: https://github.com/ghaering/pysqlite/blob/master/src/row.c#L241 y Python docs: http://docs.python.org/c-api/typeobj.html#tp_print

+2

¡Buen hallazgo! Parece que los desarrolladores de sqlite van en contra de las recomendaciones, que es probablemente la razón por la cual esto no se ve en más lugares. De los documentos: "Un tipo nunca debe implementar tp_print de una manera que produzca un resultado diferente de tp_repr o tp_str" y "se recomienda no definir tp_print, sino confiar en tp_repr y tp_str para imprimir". –

+3

He vinculado este tema en el rastreador de errores de pysqlite: http://code.google.com/p/pysqlite/issues/detail?id=4 – Ondergetekende

+0

@Ondergetekende el enlace de error se rompió, ¿terminó en otro lugar, o tendremos que abra uno nuevo (en http://bugs.python.org/?) –

0
s = str(tuple(row)) 

es una solución si desea que la representación original de cadena tupla.

Es útil por ejemplo si desea registrar la fila fácilmente como en:

logging.debug(tuple(user_row)) 

funciona porque las filas son iterable.

Cuestiones relacionadas