你已经开始熟悉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_name
和 also_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 b
为 True
的原因。
字符串 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 会重用小的、相同的字符串的内存。 | 这是一种内存优化,但不要依赖它来进行逻辑判断。 |
不可变性 | 字符串不能被修改;操作会创建新的字符串。 | 这使得代码可预测,并且在共享数据时更安全。 |
考虑内存并不仅仅是高级工程师的事情。这是编写高效、无错误代码的第一步。牢记这些概念,你就已经开始像专业人士一样思考了!