can anyone enlighten me on the differences between print sth
and print str(sth)
?
E.g. in the example from the official documentation for sqlite3, one can currently see the following code that creates a database and then uses a factory class to wrap data extracted from there:
(1) Create a database:
# I am using CPython 2.7, but I suppose 2.6 will be Ok as well
import sqlite3
conn = sqlite3.connect(":memory:")
c = conn.cursor()
c.execute('''create table stocks
(date text, trans text, symbol text, qty real, price real)''')
c.execute("""insert into stocks values ('2006-01-05','BUY','RHAT',100,35.14)""")
conn.commit()
c.close()
(2) Now using the Row
factory to produce some objects:
>>> conn.row_factory = sqlite3.Row
>>> c = conn.cursor()
>>> c.execute('select * from stocks')
<sqlite3.Cursor object at 0x7f4e7dd8fa80>
>>> r = c.fetchone()
>>> type(r)
<type 'sqlite3.Row'>
>>> r
(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.14)
As you see, we can type r
, or print r
to get this nice representation of the row object.
But what is not shown above, it is that print str(r)
will give you something different -- something more like:
<sqlite3.Row object at 0x7f4e7dd8abcd>
So I wonder if someone well-acquainted with CPython implementation can explain what print does to obtain this kind of representation from an object that does not support __str__
?
Or I guess an alternative question would be -- in the case when the above expressions give different results -- how I can obtain a string equivalent to the one that would be printed with simple print obj
?
While I was writing this and looking for some references, I have actually found the most part of the answer:
the C implementation for a Python object may implement PyObject_Print() function, which defines the way the object will be printed to a file, including stdout
;
So to get that representation, one should probably use the cStringIO module (didn't try that yet, but supposedly this should work).
Nevertheless, I will leave this question here in a hope that someone may find it useful -- or provide a better answer.
Upd. A cStringIO
example:
import cStringIO as C; s = C.StringIO(); print >>s, r, ; s.getvalue()
-- the last comma helps to get rid of the newline character(s) [ what I suppose depends on the platform ]
PS. Couple of somewhat related questions here on SO:
-- "Python print isn't using __repr__, __unicode__ or __str__ for unicode subclass?"
-- "Difference between __str__ and __repr__ in Python?"
( For example, the first question's answer answer has this nice link to the code of PyFile_WriteObject() . )
PPS. In py3k, this discrepancy seems to be gone completely.
This is the difference between __str__
and __repr__
Both methods will return a string representing the object, but:
__repr__
should return a valid Python expresion or something like <....>
if it can't produce that__str__
could return a more user friendly stringFormally, print sth
if the same as print repr(sth)
:
>>> class C:
... def __str__(self):
... return "__str__"
... def __repr__(self):
... return "__repr__"
...
>>> c = C()
>>> c
__repr__
>>> print c
__str__
>>> `c`
'__repr__'
>>> repr(c)
'__repr__'
>>> str(c)
'__str__'
Concerning the print
statement, If an object is not a string, it is first converted to a string using the rules for string conversions and concerning string conversion rules : The built-in function repr() performs exactly the same conversion in its argument as enclosing it in parentheses and reverse quotes does. The built-in function str() performs a similar but more user-friendly conversion.
EDIT: Concerning the specific case cited as an example, it appears that at C-level sqlite3.row
defines PyTypeObject.tp_print as a pointer to a custom printing function that forwards to PyTuple_Type.tp_print
. In the same time, tp_str and tp_repr are left undefined -- an so will fallback to the default object print behavior as observed.
As a conclusion, with python 2.x, print(obj)
, print(str(obj))
and print(repr(obj))
have the potential to produce three different results.
This discrepancy seems to have been lifted in 3.x as the print statement became a normal function.
# In Python 3.3:
>>> print(r)
<sqlite3.Row object at 0x7f4cedfbffd0>
>>> print(repr(r))
<sqlite3.Row object at 0x7f4cedfbffd0>
>>> print(str(r))
<sqlite3.Row object at 0x7f4cedfbffd0>
EDIT2: Still concerning the specific case of sqlite3.Row
, it appears that a row could be converted to a tuple. I have tested it both with Python 2.6 and 3.3.
Python 2.6:
>>> sys.version
'2.6.6 (r266:84292, Dec 26 2010, 22:31:48) \n[GCC 4.4.5]'
>>> type(r)
<type 'sqlite3.Row'>
>>> r
(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.140000000000001)
>>> tuple(r)
(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.140000000000001)
>>> repr(tuple(r))
"(u'2006-01-05', u'BUY', u'RHAT', 100.0, 35.140000000000001)"
Python 3.3:
>>> sys.version
'3.3.1 (default, May 28 2013, 18:34:21) \n[GCC 4.4.5]'
>>> type(r)
<type 'sqlite3.Row'>
>>> r
<sqlite3.Row object at 0x7f4cedfbffd0>
>>> tuple(r)
('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)
>>> repr(tuple(r))
"('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14)"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With