Как печать объекта приводит к другому результату, чем как str(), так и repr()?
Я тестировал некоторый код на интерпретаторе, и я заметил неожиданное поведение для класса sqlite3.Row
.
Я понял, что print obj
всегда будет иметь тот же результат, что и print str(obj)
, а ввод obj
в интерпретатор получит тот же результат, что и print repr(obj)
, однако это не относится к 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>
Я думаю, что sqlite3.Row
должен быть подклассом tuple
, но я до сих пор не понимаю, что происходит за кулисами, которые могут вызвать такое поведение. Кто-нибудь может это объяснить?
Это было проверено на Python 2.5.1, не уверен, что поведение одинаково для других версий Python.
Не уверен, имеет ли значение это значение, но атрибут row_factory
для моего Connection
был установлен в sqlite3.Row
.
Ответы
Ответ 1
PySqlite предоставляет специальный собственный hook для print
, но не реализует __repr__
или __str__
. Я бы сказал, что это немного упущенный шанс, но по крайней мере он объясняет поведение, которое вы наблюдаете.
См. источник pysqlite: https://github.com/ghaering/pysqlite/blob/master/src/row.c#L241
И документы python: http://docs.python.org/c-api/typeobj.html#tp_print
Ответ 2
s = str(tuple(row))
является обходным решением, если вы хотите получить исходное строковое представление строки.
Это полезно, например, если вы хотите легко записать строку, как в:
logging.debug(tuple(user_row))
Работает потому, что строки итерабельны.