15

这更像是我在尝试理解的 Python 模块中遇到的“有趣”现象,而不是寻求帮助(尽管解决方案也很有用)。

>>> import fuzzy
>>> s = fuzzy.Soundex(4)
>>> a = "apple"
>>> b = a
>>> sdx_a = s(a)
>>> sdx_a
'A140'
>>> a
'APPLE'
>>> b
'APPLE'

是的,所以模糊模块完全违反了 Python 中字符串的不变性。它能够做到这一点是因为它是 C 扩展吗?这是否构成 CPython 以及模块中的错误,甚至是安全风险?

另外,任何人都可以想出一种方法来解决这种行为吗?我希望能够保留字符串的原始大小写。

干杯,

亚历克斯

4

4 回答 4

13

这个错误早在二月份就解决了;更新您的版本。

要回答您的问题,是的,有几种方法可以在 C 级别修改不可变类型。在这一点上,安全影响是未知的,甚至可能是不可知的。

于 2012-04-30T03:58:02.553 回答
2

我对 CPython 不太了解,但它看起来像在fuzzy.c声明char *cs = s中,在哪里s输入__call__. 然后它 mutates cs[i],这显然会发生变异s[i],因此是原始字符串。这绝对是 Fuzzy 的一个错误,您应该将其归档在bitbucket上。正如格雷格的回答所说,使用''.join(a)将创建一个新副本。

于 2012-04-30T03:50:03.537 回答
2

我现在没有fuzzy可用于测试的模块,但以下创建了一个具有新标识的字符串:

>>> a = "hello"
>>> b = ''.join(a)
>>> b
'hello'
>>> id(a), id(b)
(182894286096, 182894559280)
于 2012-04-30T03:18:28.113 回答
0

如果它更改了不可变字符串,这是一个错误,您可以通过以下方式绕过它:

s(a.upper())
于 2012-04-30T03:49:36.653 回答