任何人都可以了解print sth
和print str(sth)
之间的差异吗?
E.g。在official documentation for sqlite3的示例中,当前可以看到以下代码创建数据库,然后使用工厂类来包装从那里提取的数据:
(1)创建数据库:
# 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)现在使用Row
工厂生成一些对象:
>>> 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)
如您所见,我们可以输入r
或print r
来获得行对象的漂亮表示。
但是上面没有显示的是print str(r)
会给你一些不同的东西 - 更像是:
<sqlite3.Row object at 0x7f4e7dd8abcd>
所以我想知道一个熟悉CPython实现的人是否可以解释什么打印从不支持__str__
的对象中获取这种表示?
或者我想另一个问题是 - 在上述表达式给出不同结果的情况下 - 我如何获得一个等同于用简单print obj
打印的字符串的字符串?
答案 0 :(得分:7)
当我写这篇文章并寻找一些参考文献时,我实际上找到了答案的大部分内容:
Python对象的C实现可以实现PyObject_Print()函数,该函数定义了对象打印到文件的方式,包括stdout
;
因此,要获得该表示,应该使用cStringIO模块(尚未尝试过,但据说这应该有效)。
尽管如此,我会在这里留下这个问题,希望有人觉得它有用 - 或提供更好的答案。
更新。一个cStringIO
示例:
import cStringIO as C; s = C.StringIO(); print >>s, r, ; s.getvalue()
- 最后一个逗号有助于摆脱换行符[我认为取决于平台]
PS。在这里有几个相关问题:SO
- "Python print isn't using __repr__, __unicode__ or __str__ for unicode subclass?"
- "Difference between __str__ and __repr__ in Python?"
(例如,第一个问题的answer答案对link的代码有很好的PyFile_WriteObject()。)
PPS。在py3k中,这种差异seems to be gone completely。
答案 1 :(得分:3)
两种方法都将返回表示对象的字符串,但是:
__repr__
应该返回有效的Python表达式或类似<....>
的内容,如果它无法生成__str__
可以返回更多用户友好字符串正式print sth
如果与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__'
关于print
声明,If an object is not a string, it is first converted to a string using the rules for string conversions以及字符串转换规则: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.
编辑:关于作为示例引用的特定案例,at C-level sqlite3.row
似乎将PyTypeObject.tp_print定义为指向自定义打印功能的指针到PyTuple_Type.tp_print
。同时,tp_str和tp_repr未定义 - 因此将回退到所观察到的默认对象打印行为。
作为结论,使用python 2.x,print(obj)
,print(str(obj))
和print(repr(obj))
有可能产生三种不同的结果。
由于print 语句成为正常的函数,这种差异似乎已在3.x中解除。
# 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:仍然关注sqlite3.Row
的具体情况,似乎可以将一行转换为元组。我用Python 2.6和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)"