Python变量

在Python中,变量是存储数据的容器,用来存储程序运行过程中需要使用的数据。

数据类型决定了变量可以存储的数据种类。Python的变量无需声明类型,赋值后即可创建,且支持动态类型。

命名规则和规范

规则
只能包含大小写字母、数字、下划线
不能以数字开头
严格区分大小写
不能使用Python内置关键字和预留关键字
规范 示例
推荐变量名使用小写字母 + 下划线(蛇形命名法) user_namemax_score
常量使用全大写 + 下划线 MAX_SIZEPI
见名知意,避免无意义的单字母 student_count 而不是 n

变量的本质

Python 中变量存储的其实是对象的引用(可以理解为指向数据的”标签”),也可以说变量是对内存及其地址的抽象

变量的存储,采用了引用语义的方式,存储的只是一个变量的值所在的内存地址,而不是这个变量本身。

变量所需的存储空间大小一致,因为变量只是保存了一个引用。也被称为对象语义和指针语义。变量的每一次初始化,都开辟了一个新的空间,将新内容的地址赋值给变量

id() 函数可以查看变量指向的内存地址:

1
2
3
4
5
6
7
8
a = 100
b = a
print(id(a)) # 例如 4378472752
print(id(b)) # 同一个地址 4378472752

a = 200
print(id(a)) # 例如 4378512757
print(id(b)) # 同一个地址 4378472752

这里 b = a 并不是把 a 的值复制一份给 b,而是让 b 也指向 a 所指向的那个 100。所以即使a重新赋值后,也不会影响b,因为b本身存储的是内存堆中的地址,而a则重新保存了新的内存地址。

如果不使用 b = a,而是各自赋一个值:

1
2
3
4
a = 100
b = 100
print(id(a)) # 例如 4378472752
print(id(b)) # 同一个地址!即使没有 b = a

ab 各自独立赋值为 100id() 居然一样——它们指向了同一个对象。但如果换成一个大数:

1
2
3
4
a = 1000
b = 1000
print(id(a)) # 例如 4380123456
print(id(b)) # 不同的地址!

这就是 Python 的小整数池(small integer caching):Python 启动时会预创建 -5256 之间的所有整数对象。程序中任何用到这个范围内的整数时,都会直接复用池中已有的对象,而不会创建新对象。

  • -5 ~ 256复用同一个对象

  • 超出这个范围:每次创建新对象

为什么是 -5256?这是 Python 开发者基于大量实际代码统计出来的——程序中出现的整数绝大多数落在这个区间。预创建它们可以避免频繁创建和销毁小整数,提升性能、节省内存。

因为这个机制,对小整数用 is 比较的结果可能”碰巧正确”,但不要依赖它。判断数值相等请始终用 ==is 只用于判断是否为同一个对象(比如和 None 比较)。

变量作用域

作用域(Scope)是指程序中变量、函数或其他标识符的可见性和可访问性范围。它决定了在代码的哪些部分可以引用或修改某个变量。

Python 中的作用域主要分为以下四种类型:

局部作用域(Local Scope)

  • 定义在函数内部的变量属于局部作用域
  • 只能在函数内部访问
  • 函数执行结束后,局部变量会被销毁

嵌套作用域(Enclosing Scope)

  • 在嵌套函数中,外层函数的作用域
  • 内层函数可以访问外层函数的变量
  • 但不包括全局变量和内置变量

全局作用域(Global Scope)

  • 定义在函数外部的变量属于全局作用域
  • 可以在整个程序中被访问
  • 需要使用 global 关键字在函数内部修改全局变量

内置作用域(Built-in Scope)

  • Python 内置的函数和变量(如 print()、len() 等)
  • 在任何地方都可以访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
x = 10  # 全局作用域

def outer():
y = 20 # 嵌套作用域

def inner():
z = 30 # 局部作用域
print(x) # 访问全局变量
print(y) # 访问嵌套作用域变量
print(z) # 访问局部变量

inner()

outer()

Python 会按照 LEGB 规则(Local -> Enclosing -> Global -> Built-in)查找变量,但不会自动在局部作用域中修改全局变量。

在函数内部修改全局变量需要使用 global 关键字声明
嵌套作用域中修改外层变量需要使用 nonlocal 关键字

变量生命周期

在Python中,变量的创建和销毁是由解释器自动管理的。创建时机是指变量首次被赋值时,解释器为其分配内存空间;销毁时机是指变量不再被引用时,解释器回收其占用的内存。

常见误区或注意事项

  1. 误认为del会立即释放内存del只是删除引用,实际内存回收由垃圾回收器(GC)决定。
  2. 循环引用导致内存泄漏:相互引用的对象可能无法被自动回收,需手动解除引用。
  3. 全局变量不会自动销毁:除非程序结束或显式删除,否则一直存在。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 变量创建
def func():
a = 10 # 变量a在函数调用时创建
print(a)

func() # 输出: 10

# 变量销毁
def func():
b = 20
print(b) # 输出: 20
return b

x = func() # 函数执行后,局部变量b被销毁,但值通过x保留
del x # 显式删除x,内存被回收