我刚刚切换到PyCharm,我很高兴它为我提供的所有警告和提示来改进我的代码。除了这个我不明白
此检查检测在外部作用域中定义的阴影名称。
我知道从外部范围访问变量是不好的做法,但阴影外部范围的问题是什么?
下面是一个例子,PyCharm给了我警告信息:
data = [4, 5, 6]
def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
print data
print_data(data)
目前投票最多、接受度最高的答案和这里的大多数答案都没有抓住重点。
这与你的函数有多长无关,也与你如何描述性地命名你的变量(希望最小化潜在的名称冲突的机会)无关。
The fact that your function's local variable or its parameter happens to share a name in the global scope is completely irrelevant. And in fact, no matter how carefully you choose you local variable name, your function can never foresee "whether my cool name yadda will also be used as a global variable in future?". The solution? Simply don't worry about that! The correct mindset is to design your function to consume input from and only from its parameters in signature. That way you don't need to care what is (or will be) in global scope, and then shadowing becomes not an issue at all.
换句话说,只有当你的函数需要使用同名的局部变量和全局变量时,阴影问题才会起作用。但是您应该首先避免这样的设计。OP的代码并没有这样的设计问题。只是PyCharm不够智能,它会发出警告以防万一。因此,为了让PyCharm开心,也为了让我们的代码干净,请参阅引用silyevsk的答案的解决方案,以完全删除全局变量。
def print_data(data):
print data
def main():
data = [4, 5, 6]
print_data(data)
main()
这是“解决”这个问题的正确方法,通过修复/删除全局的东西,而不是调整当前的局部函数。
目前投票最多、接受度最高的答案和这里的大多数答案都没有抓住重点。
这与你的函数有多长无关,也与你如何描述性地命名你的变量(希望最小化潜在的名称冲突的机会)无关。
The fact that your function's local variable or its parameter happens to share a name in the global scope is completely irrelevant. And in fact, no matter how carefully you choose you local variable name, your function can never foresee "whether my cool name yadda will also be used as a global variable in future?". The solution? Simply don't worry about that! The correct mindset is to design your function to consume input from and only from its parameters in signature. That way you don't need to care what is (or will be) in global scope, and then shadowing becomes not an issue at all.
换句话说,只有当你的函数需要使用同名的局部变量和全局变量时,阴影问题才会起作用。但是您应该首先避免这样的设计。OP的代码并没有这样的设计问题。只是PyCharm不够智能,它会发出警告以防万一。因此,为了让PyCharm开心,也为了让我们的代码干净,请参阅引用silyevsk的答案的解决方案,以完全删除全局变量。
def print_data(data):
print data
def main():
data = [4, 5, 6]
print_data(data)
main()
这是“解决”这个问题的正确方法,通过修复/删除全局的东西,而不是调整当前的局部函数。
在上面的代码片段中没有什么大问题,但是想象一下,一个函数有更多的参数和相当多的代码行。然后,您决定将数据参数重命名为yadda,但忽略了它在函数体中使用的一个地方……现在data引用全局数据,你开始有奇怪的行为——如果你没有全局名称数据,你会有一个更明显的NameError。
还要记住,在Python中一切都是对象(包括模块、类和函数),因此函数、模块或类没有不同的命名空间。另一种情况是在模块的顶部导入函数foo,并在函数体的某处使用它。然后在函数中添加一个新参数,并将其命名为- bad luck - foo。
最后,内置函数和类型也位于相同的名称空间中,可以以相同的方式隐藏。
如果你有简短的函数,良好的命名和良好的单元测试覆盖率,这些都不是什么大问题,但是,有时候你必须维护不太完美的代码,对这些可能的问题发出警告可能会有所帮助。