为什么Python字符串和元组是不可变的?

问题描述 投票:0回答:6

我不确定为什么字符串和元组被设计成不可变的;使它们不可变有哪些优点和缺点?

python string immutability tuples
6个回答
88
投票

想象一种名为 FakeMutablePython 的语言,您可以在其中使用列表赋值等方式更改字符串(例如

mystr[0] = 'a'

a = "abc"

这会在内存地址 0x1 中创建一个条目,其中包含“abc”,以及指向它的标识符

a

现在,说你愿意..

b = a

这会创建标识符

b
并将其指向 0x1 的相同内存地址

现在,如果字符串是可变的,并且您更改了

b

b[0] = 'z'

这会将存储在 0x1 的字符串的第一个字节更改为

z
.. 由于标识符
a
指向此处,因此该字符串也会更改,所以..

print a
print b

..都会输出

zbc

这可能会导致一些非常奇怪、意想不到的行为。字典键就是一个很好的例子:

mykey = 'abc'
mydict = {
    mykey: 123,
    'zbc': 321
}

anotherstring = mykey
anotherstring[0] = 'z'

现在在 FakeMutablePython 中,事情变得相当奇怪 - 你最初在字典中有两个键,“abc”和“zbc”。然后你将“abc”字符串(通过标识符

anotherstring
)更改为“zbc”,所以字典有两个键,“zbc”和“zbc”...

解决这个奇怪问题的一个解决方案是,每当您将字符串分配给标识符(或将其用作字典键)时,它都会将 0x1 处的字符串复制到 0x2。

这可以防止上述情况发生,但是如果您有一个需要 200MB 内存的字符串怎么办?

a = "really, really long string [...]"
b = a

突然你的脚本占用了 400MB 内存?这不太好。

如果我们将它指向相同的内存地址,直到我们修改它怎么办? 写入时复制。问题是,这做起来可能相当复杂..

这就是不可变性的用武之地。不需要

.replace()
方法将字符串从内存复制到新地址,然后修改它并返回。我们只需使所有字符串不可变,因此该函数必须创建一个新的字符串要返回的字符串。这解释了以下代码:

a = "abc"
b = a.replace("a", "z")

并被证明:

>>> a = 'abc'
>>> b = a
>>> id(a) == id(b)
True
>>> b = b.replace("a", "z")
>>> id(a) == id(b)
False

id()
函数返回对象的内存地址)


36
投票

一个是性能:知道 字符串是不可变的,因此很容易 在施工时就布置好—— 固定不变的存储 要求。这也是其中之一 之间的区别的原因 元组和列表。这也使得 安全地重用字符串的实现 对象。例如,CPython 实现使用预先分配的 单字符字符串的对象, 并且通常会返回原始的 string 用于字符串操作 不改变内容。

另外一个就是Python中的字符串 被视为“基本” 数字。任何活动都不会 将值 8 更改为其他值, 在Python中,没有大量的活动 会将字符串“八”更改为 还有什么。

https://web.archive.org/web/20201031092707/http://effbot.org/pyfaq/why-are-python-strings-immutable.htm


10
投票

使它们不可变的一大优点是它们可以用作字典中的键。我确信如果允许更改键,字典使用的内部数据结构会变得非常混乱。


4
投票

不可变类型在概念上比可变类型简单得多。例如,您不必像 C++ 中那样搞乱复制构造函数或常量正确性。不可变的类型越多,语言就越容易。因此,最简单的语言是没有任何全局状态的纯函数式语言(因为 lambda 演算比图灵机容易得多,而且同样强大),尽管很多人似乎并不欣赏这一点。


4
投票

Perl 具有可变字符串,并且似乎运行良好。 以上似乎是对任意设计决策的大量挥手和合理化。

我对为什么 Python 具有不可变字符串的问题的回答是,因为 Python 的创建者 Guido van Rossum 希望如此,而他现在拥有大批粉丝,他们将捍卫这一任意决定直至临终。

你可以提出一个类似的问题,为什么 Perl 没有不可变字符串,而一大群人会写不可变字符串的概念是多么糟糕,以及为什么它是 Perl 没有的最好的想法(TM)他们。


3
投票

优点:性能

缺点:你不能改变可变的。

© www.soinside.com 2019 - 2024. All rights reserved.