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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1538663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:31:37  来源:igfitidea点击:

Why are python strings and tuples are made immutable?

pythonstringimmutabilitytuples

提问by user186477

I am not sure why strings and tuples were made to be immutable; what are the advantages and disadvantage of making them immutable?

我不确定为什么字符串和元组是不可变的;使它们不可变的优点和缺点是什么?

采纳答案by Nasir

One is performance: knowing that a string is immutable makes it easy to lay it out at construction time — fixed and unchanging storage requirements. This is also one of the reasons for the distinction between tuples and lists. This also allows the implementation to safely reuse string objects. For example, the CPython implemenation uses pre-allocated objects for single-character strings, and usually returns the original string for string operations that doesn't change the content.

The other is that strings in Python are considered as "elemental" as numbers. No amount of activity will change the value 8 to anything else, and in Python, no amount of activity will change the string “eight” to anything else.

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

另一个是 Python 中的字符串被视为数字的“元素”。任何活动都不会将值 8 更改为其他任何值,并且在 Python 中,任何活动都不会将字符串“8”更改为其他任何值。

http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

回答by dbr

Imagine a language called FakeMutablePython, where you can alter strings using list assignment and such (such as mystr[0] = 'a')

想象一种名为 FakeMutablePython 的语言,您可以在其中使用列表赋值等(例如mystr[0] = 'a'

a = "abc"

That creates an entry in memory in memory address 0x1, containing "abc", and the identifier apointing to it.

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

Now, say you do..

现在,说你做..

b = a

This creates the identifier band also points it to the same memory address of 0x1

这将创建标识符b并将其指向相同的内存地址 0x1

Now, if the string were mutable, and you change b:

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

b[0] = 'z'

This alters the first byte of the string stored at 0x1 to z.. Since the identifier ais pointing to here to, thus that string would altered also, so..

z会将存储在 0x1 处的字符串的第一个字节更改为.. 由于标识符a指向此处,因此该字符串也会更改,因此..

print a
print b

..would both output zbc

.. 都会输出 zbc

This could make for some really weird, unexpected behaviour. Dictionary keys would be a good example of this:

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

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

anotherstring = mykey
anotherstring[0] = 'z'

Now in FakeMutablePython, things become rather odd - you initially have two keys in the dictionary, "abc" and "zbc".. Then you alter the "abc" string (via the identifier anotherstring) to "zbc", so the dict has two keys, "zbc" and "zbc"...

现在在 FakeMutablePython 中,事情变得很奇怪——你最初在字典中有两个键,“abc”和“zbc”..然后你将“abc”字符串(通过标识符anotherstring)更改为“zbc”,所以字典有两个键,“zbc”和“zbc”...

One solution to this weirdness would be, whenever you assign a string to an identifier (or use it as a dict key), it copies the string at 0x1 to 0x2.

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

This prevents the above, but what if you have a string that requires 200MB of memory?

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

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

Suddenly your script takes up 400MB of memory? This isn't very good.

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

What about if we point it to the same memory address, until we modify it? Copy on write. The problem is, this can be quite complicated to do..

如果我们将它指向相同的内存地址,直到我们修改它会怎样?写时复制。问题是,这可能很复杂。

This is where immutability comes in.. Instead of requiring the .replace()method to copy the string from memory into a new address, then modify it and return.. We just make all strings immutable, and thus the function must create a new string to return. This explains the following code:

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

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

And is proven by:

并被证明:

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

(the id()function returns the memory address of the object)

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

回答by Mark Ransom

One big advantage of making them immutable is that they can be used as keys in a dictionary. I'm sure the internal data structures used by dictionaries would get quite messed up if the keys were allowed to change.

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

回答by Philipp

Immutable types are conceptually much simpler than mutable ones. For example, you don't have to mess with copy constructors or const-correctness like in C++. The more types are immutable, the easier the language gets. Thus the easiest languages are the pure functional ones without any global state (because lambda calculus is much easier than Turing machines, and equally powerful), although a lot of people don't seem to appreciate this.

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

回答by phileas fogg

Perl has mutable strings and seems to function just fine. The above seems like a lot of hand waving and rationalization for an arbitrary design decision.

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

My answer to the question of why Python has immutable strings, because Python creator Guido van Rossum wanted it that way and he now has legions of fans that will defend that arbitrary decision to their dying breath.

我对为什么 Python 具有不可变字符串的问题的回答,因为 Python 的创造者 Guido van Rossum 想要这样,而且他现在拥有大量的粉丝,他们将为这个任意决定辩护到他们垂死的呼吸。

You could pose a similar question of why Perl doesn't have immutable strings and a whole passel of people would write how awful the very concept of immutable strings are and why it's The Very Bestest Idea Ever (TM) that Perl doesn't have them.

你可以提出一个类似的问题,为什么 Perl 没有不可变字符串,一大群人会写出不可变字符串的概念是多么糟糕,为什么 Perl 没有它们是 The Very Bestest Idea (TM) .

回答by easement

pros: Performance

优点:性能

cons: you can't change mutables.

缺点:你不能改变可变参数。