Python的join()无法连接对象的字符串表示(__str__)

6 投票
3 回答
3581 浏览
提问于 2025-04-16 02:20

我不太确定我哪里做错了:

>>> class Stringy(object):
...     def __str__(self):
...             return "taco"
...     def __repr__(self):
...             return "taco"
... 
>>> lunch = Stringy()
>>> lunch
taco
>>> str(lunch)
'taco'
>>> '-'.join(('carnitas',lunch))
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: sequence item 1: expected string, Stringy found

因为我在Stringy对象里加了__str__()这个方法,难道join()看见lunch的时候不应该把它当成字符串吗?

3 个回答

1

str.join的调用方式是这样的:

S.join(sequence) -> string

Return a string which is the concatenation of the strings in the
sequence.  The separator between elements is S.

注意,sequence应该是一个字符串的序列。很多对象都有__str__方法,但并不是所有的对象(比如Stringy)都是str的实例。

解决这个问题的方法其实很简单:

'-'.join(('carnitas',str(lunch)))
14

不,你得自己把它转换成字符串。

'-'.join(('carnitas',str(lunch)))

如果你需要对一系列的项目都这样做的话。

'-'.join(str(x) for x in seq)

或者

'-'.join(map(str, seq))

针对你特定的情况,你可以直接写

'carnitas-'+str(lunch)
8

''.join 这个方法在连接序列中的元素时,并不会自动调用每个元素的 __str__ 方法。其实,每个对象都有一个 __str__ 方法(即使这个方法只是从 object 继承来的),所以如果 join 是这样工作的,它就会把任何序列都连接起来(在转换成字符串后)——这往往会产生奇怪的效果。因此,最好还是让用户在需要的时候明确调用 str,毕竟“明确优于隐含”是“Python之禅”中的一句名言。

如果你想让自己的类型“变成”字符串,可以通过继承 strunicode 来实现。否则,你就需要明确调用 str 来让你的类型实例“变成”字符串。

撰写回答