Comment l'impression d'un objet peut-elle produire une sortie différente de celles de str () et de repr ()?

Je testais du code sur l'interpréteur et j'ai remarqué un comportement inattendu sur le sqlite3.Row classe.

Je croyais comprendre que print obj obtiendrait toujours le même résultat que print str (obj) et que taper obj dans l'interpréteur obtiendrait le même résultat. Le résultat est print repr (obj) , mais ce n'est pas le cas pour 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?


>>> row             # usually this would be the repr for an object
(u'string',)
>>> print repr(row) # but repr(row) is something different as well!

Je pense que sqlite3.Row doit être une sous-classe de tuple , mais je ne comprends toujours pas exactement ce qui se passe dans les coulisses et qui pourrait être à l'origine de ce problème. Quelqu'un peut-il expliquer cela?

Cela a été testé sur Python 2.5.1, pas sûr si le comportement est le même pour les autres versions de Python.

Vous ne savez pas trop si c'est important, mais row_factory L'attribut pour ma Connexion a été défini sur sqlite3.Row .

17
@ kaloyan - Je ne trouve rien qui réponde à ma question, si vous pouvez me l'indiquer.
ajouté l'auteur Andrew Clark, source
Comportement intéressant. sqlite3.Row ne semble pas sous-classer le nuplet, je suppose donc que les listes de cas spéciaux et/ou les nuplets des instructions d'impression sont basés sur d'autres critères que l'héritage, mais je ne trouve rien dans le documentation qui admettrait, beaucoup moins expliquer cela.
ajouté l'auteur millimoose, source
Avez-vous consulté stackoverflow.com/questions/1436703/& hellip; avant de poster?
ajouté l'auteur ktdrv, source

2 Réponses

PySqlite fournit le point d'ancrage spécifique pour print , mais il n'implémente pas __ repr __ ni __ str __ . Je dirais que c'est une chance manquée, mais au moins cela explique le comportement que vous observez.

See pysqlite source: https://github.com/ghaering/pysqlite/blob/master/src/row.c#L241 And python docs: http://docs.python.org/c-api/typeobj.html#tp_print

11
ajouté
J'ai lié ce sujet dans le bugtracker de pysqlite: code.google.com/ p/pysqlite/issues/detail? id = 4
ajouté l'auteur Ondergetekende, source
@CiroSantilli J'ai mis à jour ma réponse pour prendre en compte la migration vers github. La mauvaise fonctionnalité n'est toujours pas résolue
ajouté l'auteur Ondergetekende, source
Belle trouvaille! Il semble que les développeurs de sqlite se soient opposés aux recommandations, ce qui explique probablement pourquoi cela ne se voit pas ailleurs. D'après la documentation: "Un type ne doit jamais implémenter tp_print d'une manière qui produise un résultat différent de celui que tp_repr ou tp_str" "et" il est recommandé de ne pas définir tp_print, mais de s'appuyer sur tp_repr et tp_str pour l'impression ".
ajouté l'auteur Andrew Clark, source
@Ondergetekende le lien de bogue s'est rompu, s'est-il terminé ailleurs ou devons-nous en ouvrir un nouveau (à l'adresse bugs.python. org ?)
ajouté l'auteur Ciro Santilli 包子露宪 六四事件 法轮功, source
s = str(tuple(row))

est une solution de contournement si vous voulez la représentation de chaîne de tuple d'origine.

C'est utile par exemple si vous voulez enregistrer la ligne facilement comme dans:

logging.debug(tuple(user_row))

Fonctionne parce que les lignes sont itérables.

0
ajouté