简体   繁体   English

python print vs __str__?

[英]python print vs __str__?

can anyone enlighten me on the differences between print sth and print str(sth) ? 任何人都可以告诉我print sthprint str(sth)之间的区别吗?

Eg 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: 例如,在sqlite3官方文档的示例中,当前可以看到以下代码创建数据库,然后使用工厂类来包装从那里提取的数据:

(1) Create a database: (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) Now using the Row factory to produce some objects: (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)

As you see, we can type r , or print r to get this nice representation of the row object. 如您所见,我们可以输入rprint r来获得行对象的漂亮表示。

But what is not shown above, it is that print str(r) will give you something different -- something more like: 但是上面没有显示的是, print str(r)会给你一些不同的东西 - 更像是:

<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__ ? 所以我想知道是否有人熟悉CPython实现可以解释什么打印从一个不支持__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 ? 或者我想另一个问题是 - 在上述表达式给出不同结果的情况下 - 我如何获得一个等同于用简单print obj打印的字符串的字符串?

While I was writing this and looking for some references, I have actually found the most part of the answer: 当我写这篇文章并寻找一些参考文献时,我实际上找到了答案的大部分内容:

  1. 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 ; Python对象的C实现可以实现PyObject_Print()函数,它定义了对象打印到文件的方式,包括stdout ;

  2. So to get that representation, one should probably use the cStringIO module (didn't try that yet, but supposedly this should work). 因此,要获得该表示,应该使用cStringIO模块(尚未尝试,但据说这应该工作)。

Nevertheless, I will leave this question here in a hope that someone may find it useful -- or provide a better answer. 不过,我会在这里留下这个问题,希望有人可能觉得它有用 - 或提供更好的答案。

Upd. UPD。 A cStringIO example: 一个cStringIO示例:

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. PS。 Couple of somewhat related questions here on SO: 在SO上有几个相关的问题:
-- "Python print isn't using __repr__, __unicode__ or __str__ for unicode subclass?" - “Python print没有使用__repr __,__ unicode__或__str__用于unicode子类?”
-- "Difference between __str__ and __repr__ in Python?" - “Python中__str__和__repr__之间的区别?”

( For example, the first question's answer answer has this nice link to the code of PyFile_WriteObject() . ) (例如,第一个问题的答案答案有一个很好的链接PyFile_WriteObject()的代码。)

PPS. PPS。 In py3k, this discrepancy seems to be gone completely . 在py3k中,这种差异似乎完全消失了

This is the difference between __str__ and __repr__ 这是__str____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 __repr__ 应该返回一个有效的Python __repr__或类似<....>如果它不能产生它
  • __str__ could return a more user friendly string __str__ 可以返回更友好的用户字符串

Formally, print sth if the same as print repr(sth) : 正式, 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__'

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. 关于print语句, 如果对象不是字符串,则首先使用 字符串转换规则字符串转换规则 将其 转换 为字符串内置函数repr()在其参数中执行与封闭完全相同的转换它在括号和反向引号中。 The built-in function str() performs a similar but more user-friendly conversion. 内置函数str()执行类似但更加用户友好的转换。


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 . 编辑:关于作为实例引用的特定情况下,似乎在C级 sqlite3.row定义PyTypeObject.tp_print作为指针,以转发到一个自定义的打印功能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. 同时, tp_strtp_repr未定义 - 因此将回退到所观察到的默认对象打印行为。

As a conclusion, with python 2.x, print(obj) , print(str(obj)) and print(repr(obj)) have the potential to produce three different results. 作为结论,使用python 2.x, print(obj)print(str(obj))print(repr(obj))有可能产生三种不同的结果。

This discrepancy seems to have been lifted in 3.x as the print statement became a normal function . 随着印刷声明成为正常功能,这种差异似乎在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: Still concerning the specific case of sqlite3.Row , it appears that a row could be converted to a tuple. 编辑2:仍然关于sqlite3.Row的具体情况,似乎可以将行转换为元组。 I have tested it both with Python 2.6 and 3.3. 我用Python 2.6和3.3测试了它。

Python 2.6: 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: 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)"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM