Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Python字符串是不可变的?使用它们的最佳实践 使Python字符串不可变的设计原因是什么?它如何使编程更容易 我习惯了可变字符串,就像C语言中的字符串一样。没有可变字符串我怎么编程?有什么最佳实践吗_Python_String_Immutability - Fatal编程技术网

为什么Python字符串是不可变的?使用它们的最佳实践 使Python字符串不可变的设计原因是什么?它如何使编程更容易 我习惯了可变字符串,就像C语言中的字符串一样。没有可变字符串我怎么编程?有什么最佳实践吗

为什么Python字符串是不可变的?使用它们的最佳实践 使Python字符串不可变的设计原因是什么?它如何使编程更容易 我习惯了可变字符串,就像C语言中的字符串一样。没有可变字符串我怎么编程?有什么最佳实践吗,python,string,immutability,Python,String,Immutability,不可变字符串使编程更加容易,这就是为什么C#和Java也使用它们的原因 如果字符串是可变的,您将无法信任任何外部提供的字符串,因为恶意调用方可能会在您的下方更改它。 这也会使多线程变得更加困难。大多数语言都有不可变的字符串。这包括Java、Python和C#。通常在连接字符串时,语言会分配一个全新的字符串,并将两个字符串的内容复制到新字符串中 不变性确实会使编程更容易。尤其是在处理多线程环境时 不可变对象是自动线程安全的 您会发现,与C中字符串带来的极度痛苦相比,使用Python字符串非常容易

不可变字符串使编程更加容易,这就是为什么C#和Java也使用它们的原因


如果字符串是可变的,您将无法信任任何外部提供的字符串,因为恶意调用方可能会在您的下方更改它。

这也会使多线程变得更加困难。

大多数语言都有不可变的字符串。这包括Java、Python和C#。通常在连接字符串时,语言会分配一个全新的字符串,并将两个字符串的内容复制到新字符串中

不变性确实会使编程更容易。尤其是在处理多线程环境时

  • 不可变对象是自动线程安全的
  • 您会发现,与C中字符串带来的极度痛苦相比,使用Python字符串非常容易

  • 当您收到一个字符串时,您将确保它保持不变。假设您使用一个字符串参数构建一个
    Foo
    ,如下所示,然后修改该字符串;然后,
    Foo
    的名字会突然改变:

    class Foo(object):
        def __init__(self, name):
            self.name = name
    
    name = "Hello"
    foo = Foo(name)
    name[0] = "J"
    
    对于可变字符串,您必须始终进行复制,以防止不好的事情发生

    它还允许单个字符与长度为1的字符串没有区别,因此所有字符串运算符也适用于字符

    最后,如果字符串不是不可变的,您就不能可靠地将它们用作
    dict
    中的键,因为它们的哈希值可能会突然改变

    对于使用不可变字符串的编程,只需习惯以与处理数字相同的方式来处理它们:作为值,而不是对象。更改
    名称的第一个字母将是

    name = "J" + name[1:]
    

    与C字符串相比,不可变字符串极大地简化了内存分配:您不会猜测长度并过度分配,希望自己分配得足够多

    它们更安全:您可以永远不会像在C中那样发生缓冲区溢出

    只有一个可变字符串用例

    • 替换子字符串或单个字符
    所有其他字符串用例(连接、搜索等)可变性并不重要。在所有其他情况下,可变性并不重要

    如果要替换Python中的字符或子字符串,只需创建一个新字符串

    x = x[:place] + replacement + x[place+1:]
    
    这是唯一一个新颖或独特的代码


    出于我无法理解的原因,添加以下内容似乎很重要

    “除了不可变字符串外,还有其他方法可以避免字符串缓冲区溢出。”


    对于这个问题(特别是关于Python),不可变字符串有一个令人愉快的结果,即没有缓冲区溢出。对于其他语言,也适用其他原则、规则和细微差别。

    不可变字符串可以是字典和类似数据结构中的键,而无需复制字符串。在不可变字符串周围创建可变包装比在不可变字符串周围创建可变包装更容易。

    Ruby(作为一个示例)具有可变字符串,并且具有自动内存管理功能,并且不会出现缓冲区溢出。至于替换子字符串是唯一的用例,那么(就地)附加呢-1没有“就地追加”。这只是附加说明<代码>x=x+y
    。或
    x+=y
    。你不知道它是在原地还是用不可变字符串完成的。你(在31分钟前编辑之前)做了一个更一般的(而且,由于这种普遍性,是错误的)陈述,我提供了一个反例。你在回答的那部分中提到的问题(“为什么使字符串不可变?”)中没有提到C。就地追加不同于将两个不可变字符串串联起来并将结果放回变量中——这一差异对于访问(旧)字符串的所有代码来说都是显而易见的(而不是浏览更新后的变量)。我说的是Python,但为了对比可变字符串和不可变字符串(请注意,这是问题的一部分和所有答案),我提供了一个示例。这个示例不可能在Python中,因为它只有不可变字符串。特别是,就地附加(不是缩略形式的
    s=s+…
    ,而是修改字符串对象的操作)在Python中不存在。这就是我试图说明的要点。关于可以使用可变字符串但不可能使用不可变字符串的操作,您的答案不完整。我将从(现在已确认)继续我的参数公理,但它越来越荒谬了。@DavidHeffernan的评论表明,它已经被频繁和清楚地陈述过了,以至于只有一个人理解了它。我挑剔的冲动得到了满足。有一种可变的字符串类型,它被称为@JanneKarila:然而,语义大不相同。例如,它不处理Unicode字符,只处理b字节。它不是一个合适的字符串——使用字符串方法——它是一个可调整的字节数组。@JanneKarila但它是一个C字符串吗?所以我知道这有点晚了,但你能解释一下可变字符串在dicts中不可靠是什么意思吗?列表是可变的,但可以放在dicts中,什么会使可变字符串“不可靠”arsmans的意思是,你不能可靠地使用字符串作为dict的键,因为修改字符串会改变它的哈希值,这会改变字符串的存储空间。你可以通过尝试使用列表作为字典的键来查看列表(
    a={};a[[1,2]]=1
    抛出一个
    TypeError
    )。但是更改字符串很容易:
    str=list(str);str[0]=“J”;str=''。join(str)