Python 内置模块的 split 函数发生了令人疑惑的变化,这是 BUG 吗?

2021-04-23 07:53:54 +08:00
 AndyAO

从 Python 3.6.8 升级到 Python 3.9.0,执行单元测试后,发现 re.split() 的行为发生了显着的变化,但是查看相关的文档(Changelogre)却没有发现有什么变化。

这种变化可以用单元测试,较为精确的表示 :

number = '123'
def test_Asterisk_quantifier_with_capture_group(self):
    resultList = re.split(r'(\d*)', self.number)
    if platform.python_version() == '3.6.8':
        self.assertEqual(resultList,['', '123', ''])
        
    else:
        self.assertEqual(resultList,['', '123', '', '', ''])

感觉这明显不符合 split 文档中对功能的描述,还有个奇怪的现象是将*换做+后,行为仍与 3.6.8 相同。

  1. 为什么这种变化没有在文档中出现?是我没有找到它吗?
  2. 为什么行为发生了这样的变化?是引入了 BUG,还是了修复 BUG ?
1154 次点击
所在节点    问与答
4 条回复
robinjin
2021-04-23 08:38:22 +08:00
你在 Python 3.6.8 的交互模式下执行 re.split(r'(\d*)', ‘123’) ,有提示的。
jsdtxm
2021-04-23 08:40:47 +08:00
在 3.7.9 中结果为['', '123', '', '', '']。
查阅文档( https://docs.python.org/zh-cn/3.8/whatsnew/3.7.html )发现有这么一行:
“re.split() 现在支持基于匹配一个空字符串的模式例如 r'\b', '^$' 或 (?=-) 进行拆分。 (由 Serhiy Storchaka 在 bpo-25054 中贡献。)”
您看看是这个吗?
AndyAO
2021-04-23 08:54:31 +08:00
@robinjin #1
在交互模式下运行,的确看到了
FutureWarning: split() requires a non-empty pattern match.
以后遇到问题看来可以在交互模式下运行,也许会有相关的提醒

@jsdtxm #2
Split 的模式为非空的确更合理,我也认为你发的那个文档上的更改信息是正确的,看来我查错地方了,changelog 上是没有这个说明的。

虽然还是没看懂这个更改的意义,但知道了可能为空的模式有问题,以后就不会这么用了。

谢谢
AndyAO
2021-04-23 10:14:01 +08:00
在非交换模式下运行也是有提醒的,只不过颜色不太明显,在 IDEA 上会默认着色,这个比 VSCode 强。

https://cdn.jsdelivr.net/gh/Andy-AO/GitHubPictureBed/img/20210423101302.png

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/772603

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX