【问题标题】:Python strings immutable?Python字符串不可变?
【发布时间】:2012-12-18 11:55:55
【问题描述】:

Python 字符串应该像整数一样是不可变的。考虑一下:

>>> num1 = 34
>>> num2 = 36
>>> id(num1)
505894832
>>> num4 = 34
>>> id(num4)
505894832

num4 与 num1 具有完全相同的 ID,这意味着它们指向同一事物。字符串不应该发生同样的事情吗?我很困惑:

>>> name = "Sumeet"
>>> id(name)
35692000
>>> name = "Ali"
>>> id(name)
35926912
>>> naam = "Sumeet"
>>> id(naam)
35926848

最后的输出不应该是:35692000吗?

【问题讨论】:

  • 不可变只是意味着它们不能被修改。与同一个字符串是否有多个副本无关。
  • 另外,python 实习低整数并重用它们。毕竟它们是不可变的。你真的只需要 1 个号码 1.. 的副本
  • 那么,对于字符串,我们是否需要多个副本说同一个“Hello”...它们也是不可变的?
  • 另外:Python 可以重用内存地址。 id() 不保证是唯一的。
  • 你为什么会担心这个问题?

标签: python string python-3.x immutability


【解决方案1】:

多个变量具有相同 id 的事实与实际对象是不可变的没有太大关系。

事实上,由于它们的不变性,这可以安全地发生(节省内存)。

假设python中的字符串不是不可变的,你声明:

a = 'abc'

b = 'abc'

如果您更改了a,则意味着b 将引用一个完全不同的对象(复制表示相同文字字符串所需的内存),或者当a 更改时,整个对象必须复制才能进行更改(这样 b 不会受到影响)。

由于字符串是不可变的,因此两个变量可以安全地指向同一个对象。对不可变数据结构的任何更改都会创建一个新结构,并且指向它的引用将更改为新结构,而对“旧”结构的所有其他引用保持不变。不可变数据结构中没有副作用大大降低了由于共享结构/对象在代码中的其他位置被更改而发生错误的可能性。

【讨论】:

    【解决方案2】:

    CPython 实习生了一些非常小的整数和非常小的字符串,但你不能依赖它,因为它依赖于实现。

    因此,以下是您的发现的一些反例:

    >>> a = 123456
    >>> b = 123456
    >>> id(a)
    30497296
    >>> id(b)
    30496144
    >>> a = "hey"
    >>> b = "hey"
    >>> id(a)
    44067112
    >>> id(b)
    44067112
    

    【讨论】:

    • 这是否意味着“该值可能会或可能不会在该地址保持安全”..?
    • @NikhilKhullar:从 Python 的角度来看,这个问题没有任何意义。该语言不会公开“地址”或“指针”以确保安全。您只需要知道字符串、元组和整数是不可变的,而列表/字典/集合则不是。由于您不能更改字符串,因此将多个名称绑定到同一个字符串是安全的,是的,但您不必担心这一点。你需要知道你永远不应该使用is 进行相等比较,只能使用==,因为"hey" is "hey" 可能是True"Sumeet" is "Sumeet" 可能是False
    【解决方案3】:

    不,它并不指向同一件事,原因很简单。

    当你这样做时:

    name = 'Sumeet'
    

    您实际上创建了一个新的string 对象并将其绑定到name 引用。当你这样做时:

    naam = 'Sumeet'
    

    您再次创建了一个 NEW string 对象并将其绑定到 naam 引用。为了让它们指向同一个对象,你应该这样做:

    naam = name

    这使得naam 引用name 引用的同一对象。


    关于整数,Python 的CPython 实现具有缓存小整数的功能。例如,根据this source,python 3.2 缓存了从-5256 的整数对象。

    【讨论】:

    • 正是我需要的信息。这个概念现在很清楚,缓存让我感到困惑......
    • @NikhilKhullar 很高兴能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2015-04-15
    • 2015-07-02
    • 2014-09-28
    • 2015-02-26
    • 2018-06-18
    • 2020-06-26
    • 2016-08-11
    相关资源
    最近更新 更多