Python编程
Completion requirements
变量
在 Python 中,变量是通过赋值自动声明的。变量总是引用对象,并且永远没有类型。变量仅存在于当前作用域或全局作用域。当它们超出作用域时,变量会被销毁,但它们引用的对象不会(除非引用该对象的次数降为零)。
作用域由函数和类块来划定。函数和它们的作用域可以是嵌套的。因此,以下代码是有效的:
def foo():
def bar():
x = 5 # x现在在作用域内
return x + y # y在后续的外部作用域中定义
y = 10
return bar() # 当y被定义时,bar的作用域包括y
运行测试时:
>>> foo()
15
>>> bar()
Traceback (most recent call last):
File "<pyshell#26>", line 1, in -toplevel-
bar()
NameError: name 'bar' is not defined
因为 bar
的作用域是嵌套的,所以在外部作用域无法访问它。
一个常见的陷阱是没有在使用之前给变量赋值。比如:
>>> for x in range(10):
y.append(x) # append 是列表的一个方法
错误提示:
Traceback (most recent call last):
File "<pyshell#46>", line 2, in -toplevel-
y.append(x)
NameError: name 'y' is not defined
要解决这个问题,必须在 for
循环执行之前加上 y = []
。
一个循环不会创建它自己的作用域:
for x in [1, 2, 3]:
inner = x
print(inner) # 输出 3,而不是错误
global 关键字
Python 模块中的全局变量可以被该模块中的函数读取。如果它们是可变的,还可以通过方法调用进行修改。然而,除非在函数中声明为 global
,否则不能通过直接赋值来修改它们。
例如:
count1 = 1
count2 = 1
list1 = []
list2 = []
def test1():
print(count1) # 读取访问没有问题,引用全局变量
def test2():
try:
print(count1) # 这个 try 块有问题...
count1 += 1 # count1 += 1 会让 count1 成为局部变量,但局部变量没有定义。
except UnboundLocalError as error:
print("Error caught:", error)
def test3():
list1 = [2] # 不影响外部;这将 list1 定义为局部变量
def test4():
global count2, list2
print(count1) # 读取访问没有问题,引用全局变量
count2 += 1 # 通过赋值修改 count2
list1.append(1) # 影响全局的 list1,即使没有 global 声明,因为它是方法调用
list2 = [2] # 通过赋值修改 list2
test1()
test2()
test3()
test4()
print("count1:", count1) # 输出 1
print("count2:", count2) # 输出 2
print("list1:", list1) # 输出 [1]
print("list2:", list2) # 输出 [2]
nonlocal 关键字
nonlocal
关键字(自 Python 3.0 起可用)是 global
关键字的类似物,用于嵌套作用域。它允许嵌套函数修改外部函数中的不可变变量。
例如:
# 需要 Python 3
def outer():
outerint = 0
outerint2 = 10
def inner():
nonlocal outerint
outerint = 1 # 只有通过 nonlocal 声明,才能影响外部的 outerint
outerint2 = 1 # 没有影响
inner()
print(outerint) # 输出 1
print(outerint2) # 输出 10
outer()
如果在 Python 2 中模拟 nonlocal
,可以通过可变对象实现:
def outer():
outerint = [1] # 技巧1:将整数存储在列表中
class outerNL: pass # 技巧2:将整数存储在类中
outerNL.outerint2 = 11
def inner():
outerint[0] = 2 # 可以修改列表成员
outerNL.outerint2 = 12 # 可以修改类成员
inner()
print(outerint[0]) # 输出 2
print(outerNL.outerint2) # 输出 12
outer()
globals 和 locals
要找出在全局和局部作用域中存在哪些变量,可以使用 locals()
和 globals()
函数,它们返回字典:
int1 = 1
def test1():
int1 = 2
globals()["int1"] = 3 # 写入访问似乎是可能的
print(locals()["int1"]) # 输出 2
test1()
print(int1) # 输出 3
Python 文档不建议对 locals()
字典进行写入操作。
【链接】:
Last modified: Friday, 31 January 2025, 12:22 AM