一、变量基础
1. 变量定义与命名
基本规则:
变量名 = 值
命名规范:
只能包含字母、数字和下划线(A-z, 0-9, _)
不能以数字开头
区分大小写
避免使用Python关键字
PEP8命名约定:
普通变量:snake_case(如:student_name)
常量:UPPER_CASE(如:MAX_SIZE)
类名:PascalCase(如:ClassName)
私有变量:_single_leading_underscore
表1 Python变量命名示例
应用案例:
# 合法变量定义
user_name = "Alice"
user_age = 25
is_active = True
MAX_RETRIES = 3
# 多重赋值
x, y, z = 1, 2, 3
# 链式赋值
a = b = c = 0
# 实际应用:坐标转换
latitude, longitude = 40.7128, -74.0060
print(f"纬度: {latitude}, 经度: {longitude}")
二、变量作用域
1. 作用域层级
四种作用域:
局部作用域(Local)
嵌套作用域(Enclosing)
全局作用域(Global)
内置作用域(Built-in)
Python作用域层级关系
内置作用域(Built-in)
全局作用域(Global)
嵌套作用域(Enclosing)
局部作用域(Local)
各层作用域特点:
应用案例:
global_var = "全局变量" # 全局作用域
defouter_func():
outer_var = "外层变量"# 嵌套作用域
definner_func():
local_var = "局部变量"# 局部作用域
print(outer_var) # 访问嵌套作用域
print(global_var) # 访问全局作用域
inner_func()
# print(local_var) # 报错,无法访问局部变量
outer_func()
print(global_var) # 访问全局变量
# print(outer_var) # 报错,无法访问嵌套作用域
2. LEGB规则
查找顺序:
查找流程图:
表2 LEGB规则示例
应用案例:
x = "global x" # 全局变量
defouter():
x = "outer x"# 嵌套作用域
definner():
x = "inner x"# 局部变量
print(x) # 输出: inner x
inner()
print(x) # 输出: outer x
outer()
print(x) # 输出: global x
三、全局与局部变量
1. global关键字
使用方法:
global 变量名
应用案例:
count = 0 # 全局变量
def increment():
global count # 声明使用全局变量
count += 1
increment()
print(count) # 输出: 1
global关键字作用示意图
[函数内部] [global声明] [直接修改全局变量]
而非创建局部变量
2. nonlocal关键字
使用方法:
nonlocal 变量名
应用案例:
def outer():
x = "original"
definner():
nonlocal x # 声明使用嵌套作用域变量
x = "modified"
inner()
print(x) # 输出: modified
outer()
表3 global vs nonlocal
四、可变对象与作用域
1. 可变对象陷阱
典型问题:
def append_to(element, target=[]): # 默认参数在定义时创建
target.append(element)
return target
print(append_to(1)) # [1]
print(append_to(2)) # [1, 2] # 不是预期的[2]
修正方案:
def append_to(element, target=None):
target = target or []
target.append(element)
return target
可变默认参数问题图解
函数定义时创建默认列表
多次调用共享同一列表对象
意外累积元素
2. 作用域与性能
访问速度比较:
import timeit
deftest_local():
x = 100
return x
deftest_global():
return x # 全局x
x = 100
print("局部变量访问:", timeit.timeit(test_local, number=1000000))
print("全局变量访问:", timeit.timeit(test_global, number=1000000))
表4 变量访问性能
五、高级作用域应用
1. 闭包与作用域
闭包示例:
def make_counter():
count = 0# 嵌套作用域变量
defcounter():
nonlocal count
count += 1
return count
return counter
counter = make_counter()
print(counter()) # 1
print(counter()) # 2
闭包作用域示意图
[make_counter作用域]
├── count变量
└── [counter函数]
├── 保持对count的引用
└── 形成闭包
2. 类属性作用域
类作用域特点:
class MyClass:
class_var = "类变量"# 类作用域
def__init__(self):
self.instance_var = "实例变量"# 实例作用域
print(MyClass.class_var) # 访问类变量
obj = MyClass()
print(obj.instance_var) # 访问实例变量
表5 类变量与实例变量
六、实践与常见错误
1. 作用域实践
推荐做法:
# 1. 最小化全局变量
config = { # 使用配置字典替代多个全局变量
'timeout': 30,
'max_retries': 3
}
# 2. 明确变量作用域
defprocess_data(data):
result = [] # 明确局部变量
for item in data:
processed = transform(item) # 明确局部变量
result.append(processed)
return result
# 3. 使用常量替代魔法数字
MAX_CONNECTIONS = 10# 全大写命名常量
defconnect():
if current_connections >= MAX_CONNECTIONS:
raise RuntimeError("达到最大连接数")
2. 常见错误与修复
错误案例:
# 错误1:意外创建局部变量
total = 0
defcalculate():
total += 1# 报错,尝试修改全局但实际创建局部变量
return total
# 修正:
defcalculate():
global total
total += 1
return total
# 错误2:循环变量泄漏
for i inrange(5):
pass
print(i) # 输出4(Python没有块级作用域)
# 修正:避免依赖循环变量
result = []
for i inrange(5):
result.append(i*2)
print(result) # 明确使用结果列表
# 错误3:闭包变量延迟绑定
functions = []
for i inrange(3):
functions.append(lambda: print(i))
for f in functions:
f() # 都输出2,不是预期的0,1,2
# 修正:立即绑定
functions = []
for i inrange(3):
functions.append(lambda x=i: print(x)) # 使用默认参数立即绑定
作用域错误检查流程
总结
本教程全面讲解了Python变量及作用域:
核心概念:
变量定义与命名规范
LEGB作用域规则
global与nonlocal关键字
高级主题:
闭包与作用域
类作用域特性
可变对象陷阱
实践建议:
最小化全局变量
明确变量作用域
避免常见陷阱
关键记忆点:
变量查找遵循LEGB规则
修改全局变量需要global声明
嵌套函数修改外部变量需要nonlocal
避免可变对象作为默认参数
类变量与实例变量作用域不同
Python变量作用域知识图谱
更新日期:2025-05-09
交流讨论:欢迎在评论区留言!
重要提示:本文主要是记录自己的学习与实践过程,所提内容或者观点仅代表个人意见,只是我以为的,不代表完全正确,不喜请勿关注。
领取专属 10元无门槛券
私享最新 技术干货