9

谁能告诉我print sth和之间的区别print str(sth)

例如,在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 实现的人可以解释 print 如何从不支持的对象中获取这种表示__str__

或者我猜另一个问题是——在上述表达式给出不同结果的情况下——我如何获得一个与将用 simple 打印的字符串等效的字符串print obj

4

2 回答 2

7

当我写这篇文章并寻找一些参考资料时,我实际上找到了大部分答案:

  1. Python 对象的 C 实现可以实现PyObject_Print()函数,该函数定义了将对象打印到文件的方式,包括stdout

  2. 因此,要获得这种表示,可能应该使用cStringIO模块(还没有尝试过,但应该可以工作)。

不过,我将把这个问题留在这里,希望有人会觉得它有用——或者提供更好的答案。

更新。一个cStringIO例子:

import cStringIO as C; s = C.StringIO(); print >>s, r, ; s.getvalue()  

- 最后一个逗号有助于摆脱换行符[我认为取决于平台]

PS。这里有几个相关的问题:
-- “Python print 没有使用 __repr__、__unicode__ 或 __str__ 作为 unicode 子类?”
-- “Python 中 __str__ 和 __repr__ 的区别?”

(例如,第一个问题的答案有这个很好的链接PyFile_WriteObject()的代码。)

聚苯乙烯。在 py3k 中,这种差异似乎完全消失了

于 2013-06-04T09:51:02.973 回答
3

__str__这是和之间的区别__repr__

两种方法都将返回一个表示对象的字符串,但是:

  • __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语句,如果对象不是字符串,则首先使用字符串转换规则和字符串转换规则将其转换为字符串:内置函数 repr() 在其参数中执行与封闭它完全相同的转换在括号和反引号中。内置函数 str() 执行类似但对用户更友好的转换。


编辑:关于作为示例引用的特定案例,似乎在 C 级别 sqlite3.rowPyTypeObject.tp_print定义为指向自定义打印函数的指针,该函数转发到PyTuple_Type.tp_print. 同时,tp_strtp_repr未定义——因此将退回到观察到的默认对象打印行为。

作为一个结论,使用 python 2.x,print(obj)print(str(obj))print(repr(obj))可能产生三种不同的结果。

这种差异在 3.x 中似乎已经消除,因为 print语句成为了正常功能

# 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 对其进行了测试。

蟒蛇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)"

蟒蛇 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)"
于 2013-06-04T10:10:07.760 回答