Python命名遮蔽困惑
我有一些代码,类似于这个(这段代码虽然没什么用,但能复现我的问题):
def fn():
l = ["foo", "bar", "baz"]
print map( lambda f : len(f), l )
for i, f in enumerate(l):
print i, f
然后,PyCharm 提示我说我声明的 lambda f
“遮蔽了外部作用域的名字 f”。这似乎是因为在接下来调用 enumerate()
的时候,变量被重复使用了。
这段代码的运行结果是正常的,但这里到底发生了什么呢?我是不是可以理解为 Python 认为 f
是 fn
里的一个局部变量,并警告我在 lambda 里面使用的 f
和本地定义的 f
不会是同一个变量——即使 lambda 里先用的是变量名 f
呢?
除了重命名变量,还有没有什么好的做法来避免这种情况?或者在这种情况下,我是不是可以凭自己的判断忽略这个警告?
1 个回答
1
在函数的定义中,只要你给一个变量赋值,这个变量就会变成函数内部的局部变量。举个更常见的例子:
x = 3
def foo():
print x
x = 2
foo()
当你定义了一个叫 foo
的函数时,如果里面有 x = 2
这行代码,而之前没有写 global x
,那么 x
就会成为这个函数的局部变量。当你调用 foo
时,局部变量 x
在 print x
被调用时还没有定义,这样就会出现一个叫 UnboundLocalError
的错误。即使外面有一个同名的全局变量,这也没关系。
在你的例子中,for
循环实际上是对变量 f
的一种隐式赋值,所以 f
只在 fn
函数内部有效。这个警告是告诉你,当你要计算 len(f)
时,lambda
里的参数 f
会优先于 fn
函数内部的 f
的值。