首页 论坛 置顶 Python 字符串与内存:每位初级开发者应了解的知识

正在查看 1 个帖子:1-1 (共 1 个帖子)
  • 作者
    帖子
  • #26143

    你已经开始熟悉Python了。你可以切片和处理字符串,使用.format(),甚至可能还用过一两个f-string。但你有没有停下来想过,当你写name = "Alice"时,背后发生了什么?

    了解一些关于内存的知识会让你成为更好的程序员。这有助于解释一些“奇怪”的行为,并让你更批判性地思考你的代码。让我们来分解一下。

    1. 变量是标签,而不是盒子

    这是最重要的概念。一个常见的初学者思维模型是,变量是一个放置数据的盒子。

    my_name = "Alice"
    # 想象一下: [ my_name ] -> 包含 "Alice"

    一个更准确的模型是,变量是一个标签名称标签,你将其贴在一段数据上。

    my_name = "Alice"  # 在内存中创建字符串 "Alice",并标记为 `my_name`
    also_my_name = my_name # 将另一个标签(`also_my_name`)贴在同一字符串 "Alice" 上。

    这有什么重要性?这意味着 my_namealso_my_name 指向你计算机内存中的 完全相同 的字符串。这是高效的!Python 不会浪费内存去创建两个相同的副本,除非你明确告诉它这样做。


    2. “is” 与 “==” 的谜团解开

    这直接引出了一个经典的初级面试问题:is== 之间有什么区别?

      • == 检查 相等性。它问的是:“这两个变量的 是相同的吗?”
      • is 检查 身份。它问的是:“这两个变量是否指向内存中的 完全相同的对象?”

    让我们看看实际情况:

    a = "hello"  # 字符串字面量,硬编码在程序中
    b = "hello"  # 另一个具有相同值的字符串字面量
    c = "hello world!"[:5]  # 一个动态表达式,在运行时创建一个新的字符串 "hello"
    
    print(a == b) # True - 相同的值
    print(a is b) # True!等等,为什么?(我们将在下文解释)
    print(a == c) # True - 相同的值
    print(a is c) # False!它们在内存中是不同的对象。

    那么,为什么 a is b 也为 True 呢?这引入了我们的下一个概念。


    3. Python 的内存技巧:字符串驻留

    为了节省内存,Python 自动驻留小的、常见的字符串(和整数)。这意味着它在内存中只创建一个副本,并将所有变量指向该单一副本。

    字符串 "hello" 短且常见。当你写 b = "hello" 时,Python 足够聪明,能够找到内存中已有的 "hello" 并将 b 指向它。这就是为什么 a is bTrue 的原因。

    字符串 c 是通过切片一个较大的字符串动态创建的 ("hello world!"[:5])。虽然它的值是 "hello",但 Python 的字符串驻留行为在这里并不一致,因此它通常会在内存中成为一个新的、独立的对象。因此,a is c 的结果是 False

    ⚠️ 初学者要点: 始终使用 == 来检查字符串值。 字符串驻留是一种 Python 为提高效率而使用的内存优化,但这不是你应该依赖于程序逻辑的规则。只有在你特别想检查内存中是否是同一个对象时,才使用 is(这种情况要少得多)。


    4. 为什么不可变性是你的朋友

    Python 中的字符串是 不可变的。这是一个复杂的词,意思是“不能被改变”。

    你不能这样做:

    my_string = "pizza"
    my_string[0] = "P" # TypeError! 不能改变现有字符串。

    你只能创建新的字符串:

    my_string = "pizza"
    my_new_string = "P" + my_string[1:] # 创建一个全新的字符串 "Pizza"
    # 变量 `my_string` 现在被重新分配给一个新对象。
    # 旧字符串 "pizza" 最终会被 Python 清理掉。

    这与内存有关,因为它是安全的。由于字符串不能改变,Python可以自由地共享它们(通过驻留)而不必担心更改一个变量会意外更改另一个变量。


    你的快速备忘单

    概念 含义 初学者为何应该关心
    变量作为标签 变量名绑定到对象,而不是“包含”对象。 解释了为什么赋值变量不会复制数据。
    is== is 是身份(同一对象),== 是相等(同一值)。 始终使用 == 来比较字符串。 这可以避免潜在的错误。
    字符串驻留 Python 会重用小的、相同的字符串的内存。 这是一种内存优化,但不要依赖它来进行逻辑判断。
    不可变性 字符串不能被修改;操作会创建新的字符串。 这使得代码可预测,并且在共享数据时更安全。

    考虑内存并不仅仅是高级工程师的事情。这是编写高效、无错误代码的第一步。牢记这些概念,你就已经开始像专业人士一样思考了!

正在查看 1 个帖子:1-1 (共 1 个帖子)
  • 哎呀,回复话题必需登录。