使用 __str__ 表示来打印容器中的对象
我注意到,当具有重载 __str__ 方法的实例作为参数传递给 print 函数时,它会按预期打印。但是,当将包含这些实例之一的容器传递给 print
时,它会使用 __repr__
方法。也就是说,print(x)
显示了x
的正确字符串表示,并且print(x, y)
工作正常,但是< code>print([x]) 或 print((x, y))
会打印 __repr__
表示形式。
首先,为什么会发生这种情况?其次,在这种情况下有没有办法纠正 print
的行为?
I've noticed that when an instance with an overloaded __str__
method is passed to the print
function as an argument, it prints as intended. However, when passing a container that contains one of those instances to print
, it uses the __repr__
method instead. That is to say, print(x)
displays the correct string representation of x
, and print(x, y)
works correctly, but print([x])
or print((x, y))
prints the __repr__
representation instead.
First off, why does this happen? Secondly, is there a way to correct that behavior of print
in this circumstance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用对象的
__str__
的容器的问题是完全不明确的——比如说,如果print L
显示[1, 2],这意味着什么?
L
可以是['1, 2']
(单个项目列表,其字符串项目包含逗号)或四个 2 项目列表中的任何一个(因为每个项目都可以是字符串或整数)。当然,类型的歧义对于print
来说很常见,但是项目数量的总歧义(因为每个逗号可能分隔项目或部分)字符串项目)是决定性的考虑因素。The problem with the container using the objects'
__str__
would be the total ambiguity -- what would it mean, say, ifprint L
showed[1, 2]
?L
could be['1, 2']
(a single item list whose string item contains a comma) or any of four 2-item lists (since each item can be a string or int). The ambiguity of type is common forprint
of course, but the total ambiguity for number of items (since each comma could be delimiting items or part of a string item) was the decisive consideration.我不确定为什么列表的
__str__
方法返回其中包含的对象的__repr__
- 所以我查了一下:< a href="http://mail.python.org/pipermail/python-3000/2008-May/013876.html" rel="noreferrer">[Python-3000] PEP: str(container) 应该调用 str(item ),而不是 repr(item)因此更清楚列表中到底是什么(因为对象的字符串表示形式可能包含逗号等)。根据 Guido "BDFL" van Rossum 的说法,这种行为不会消失:
现在,有两种方法可以解决您的代码的此问题。
第一个是子类
list
并实现您自己的__str__
方法。现在来测试一下:
我个人认为这是一个糟糕的主意。某些函数 - 例如
random.sample
,如演示的那样 - 实际上返回list
对象 - 即使您对列表进行了子类化。因此,如果您采用此路线,可能会有大量result = strList(function(mylist))
调用,这可能会导致效率低下。这也是一个坏主意,因为这样您可能有一半的代码使用常规list
对象,因为您不打印它们,而另一半则使用strList
对象,这可能会导致您的代码变得更加混乱和混乱。尽管如此,选项仍然存在,并且这是让print
函数(或语句,对于 2.x)按照您希望的方式运行的唯一方法。另一个解决方案是编写您自己的函数
strList()
,它以您想要的方式返回字符串:不幸的是,这两种解决方案都要求您重构现有代码 - 但
str(容器)
将会继续存在。I'm not sure why exactly the
__str__
method of a list returns the__repr__
of the objects contained within - so I looked it up: [Python-3000] PEP: str(container) should call str(item), not repr(item)So it's more clear about what exactly is in the list (since the object's string representation could have commas, etc.). The behavior is not going away, per Guido "BDFL" van Rossum:
Now, there are two ways to resolve this issue for your code.
The first is to subclass
list
and implement your own__str__
method.And now to test it:
I personally think this is a terrible idea. Some functions - such as
random.sample
, as demonstrated - actually returnlist
objects - even if you sub-classed lists. So if you take this route there may be a lot ofresult = strList(function(mylist))
calls, which could be inefficient. It's also a bad idea because then you'll probably have half of your code using regularlist
objects since you don't print them and the other half usingstrList
objects, which can lead to your code getting messier and more confusing. Still, the option is there, and this is the only way to get theprint
function (or statement, for 2.x) to behave the way you want it to.The other solution is just to write your own function
strList()
which returns the string the way you want it:Both solutions require that you refactor existing code, unfortunately - but the behavior of
str(container)
is here to stay.因为当你打印列表时,通常你是从程序员的角度来看,或者是调试。如果您打算显示列表,则需要以有意义的方式处理其项目,因此使用 repr。
如果您希望在容器中打印对象,请定义 repr
当然,repr 应该返回一个字符串,该字符串可用作重新创建对象的代码,但您可以执行您想要的操作。
Because when you print the list, generally you're looking from the programmer's perspective, or debugging. If you meant to display the list, you'd process its items in a meaningful way, so repr is used.
If you want your objects to be printed while in containers, define repr
Of course, repr should return a string that could be used as code to recreate your object, but you can do what you want.