为什么``' {x [1:3]}' .format(x =; asd; asd; quord; quary)`导致typeerror?
考虑一下:
>>> '{x[1]}'.format(x="asd")
's'
>>> '{x[1:3]}'.format(x="asd")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string indices must be integers
这种行为的原因可能是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基于, checking what value the object's
__getitem__
method actually receives:Output (
“ rel =“ noreferrer” title = int ,
4:6
没有像通常的切片一样转换为切片(4,6,无)
。相反,它只是 string'4:6'
。这不是用于索引/切片字符串的有效类型,因此typeError:字符串索引必须是您获得的整数
。更新:
记录了吗?好吧...我看不到很清楚的东西,但是 @gacy20 grammar 这些规则
我们的
c [ 4:6]
是field_name
,我们对element_index
part4:6
感兴趣。我认为,如果Digit+
有自己的规则,我会说有有意义的名称:我要说
index_integer
和index_string更清楚地表明dig> digit+ index_integer
>将转换为 integer (而不是保持数字字符串),而&lt;除了“]”&gt; +
将保持字符串。也就是说,看着规则,也许我们应该认为“将数字案件与任何字符案件中分开是什么意义?” 并认为这一点是对纯数字的处理方式有所不同,大概是将其转换为整数。或者也许文档的其他部分甚至指出
Digit
或数字+
在一般中被转换为整数。An experiment based on your comment, checking what value the object's
__getitem__
method actually receives:Output (Try it online!):
So while the
4
gets converted to anint
, the4:6
isn't converted toslice(4, 6, None)
as in usual slicing. Instead, it remains simply the string'4:6'
. And that's not a valid type for indexing/slicing a string, hence theTypeError: string indices must be integers
you got.Update:
Is that documented? Well... I don't see something really clear, but @GACy20 pointed out something subtle. The grammar has these rules
Our
c[4:6]
is thefield_name
, and we're interested in theelement_index
part4:6
. I think it would be clearer ifdigit+
had its own rule with meaningful name:I'd say having
index_integer
and index_string would more clearly indicate thatdigit+
is converted to an integer (instead of staying a digit string), while<any source character except "]"> +
would stay a string.That said, looking at the rules as they are, perhaps we should think "what would be the point of separating the digits case out of the any-characters case which would match it as well?" and think that the point is to treat pure digits differently, presumably to convert them to an integer. Or maybe some other part of the documentation even states that
digit
ordigits+
in general gets converted to an integer.'{x[1]}'.format(x="asd")
这里的[1]
语法不是“正常”字符串索引语法,即使在在这种情况下,它似乎以同样的方式工作。它使用格式规范迷你语言。相同的机制允许传递对象并访问格式化字符串内的任意属性(例如
'{x.name}'.format(x=some_object)
)。这种“假”索引语法还允许将可索引对象传递给
format
并直接从格式化字符串中获取所需的元素:在文档是这一段:
虽然它提到
它没有提及任何有关不支持切片语法的内容。
对我来说,这感觉像是文档中的疏忽,特别是因为
'{x[1:3]}'.format(x="asd")
生成如此神秘的错误消息,甚至更是如此由于__getitem__
已经支持切片。'{x[1]}'.format(x="asd")
the[1]
syntax here is not the "normal" string indexing syntax, even if in this case it appears to be working the same way.It is using the Format Specification Mini-Language. The same mechanism that allows for passing objects and accessing an arbitrary attribute inside the formatted string (eg
'{x.name}'.format(x=some_object)
).This "fake" indexing syntax also allows to pass indexable objects to
format
and directly getting the element you want from within the formatted string:The only reference (that I could find, at least) for this in the docs is this paragraph:
While it mentions
it does not mention anything about slicing syntax not being supported.
For me this feels like an oversight in the docs, especially because
'{x[1:3]}'.format(x="asd")
generates such a cryptic error message, and even more so due to__getitem__
already supporting slicing.