我一直在玩 startswith()
,我发现了一些有趣的东西:
>>> tup = ('1', '2', '3')
>>> lis = ['1', '2', '3', '4']
>>> '1'.startswith(tup)
True
>>> '1'.startswith(lis)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: startswith first arg must be str or a tuple of str, not list
现在,错误很明显,将列表转换为元组将像最初那样工作得很好:
>>> '1'.startswith(tuple(lis))
True
现在,我的问题是:为什么第一个参数必须是 str 或 str 前缀的元组,而不是 str 前缀的列表?
据我所知,startswith()
的 Python 代码可能如下所示:
def startswith(src, prefix):
return src[:len(prefix)] == prefix
但这只会让我更加困惑,因为即使考虑到这一点,无论是列表还是元组,它仍然应该没有任何区别。我错过了什么?
最佳答案
技术上没有理由接受其他序列类型,不。 source code大致是这样的:
if isinstance(prefix, tuple):
for substring in prefix:
if not isinstance(substring, str):
raise TypeError(...)
return tailmatch(...)
elif not isinstance(prefix, str):
raise TypeError(...)
return tailmatch(...)
(tailmatch(...)
执行实际匹配工作)。
所以是的,任何可迭代对象都适用于 for
循环。但是,所有其他采用多个值的字符串测试 API(以及 isinstance()
和 issubclass()
)也只接受元组,这告诉用户API 的安全假设值不会被改变。您不能改变元组,但该方法理论上可以改变列表。
另请注意,您通常测试固定数量的前缀或后缀或类(在 isinstance()
和 issubclass()的情况下)
);该实现不适合大量 元素。元组意味着您的元素数量有限,而列表可以任意大。
接下来,如果任何可迭代或序列类型是可接受的,那么它将包括字符串;单个字符串也是一个序列。那么应该将单个字符串参数视为单独的字符,还是视为单个前缀?
所以换句话说,序列不会发生变化是对自文档的限制,与其他 API 一致,它暗示要测试的项目数量有限,并消除了关于如何进行测试的歧义应处理单个字符串参数。
请注意,这是之前在 Python Ideas 列表中提出的;见this thread ; Guido van Rossum 的主要论点是,您要么是单个字符串的特殊情况,要么只接受一个元组。他选择了后者,认为没有必要改变这一点。
关于python - str.startswith 是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53721675/