在外部作用域中定义的阴影名称有什么问题?

2024-05-19 22:11:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚切换到PyCharm,我很高兴它为我提供了所有的警告和提示来改进我的代码。除了这个我不明白的:

This inspection detects shadowing names defined in outer scopes.

我知道从外部作用域访问变量是不好的做法,但隐藏外部作用域有什么问题

这里有一个例子,PyCharm给了我一条警告信息:

data = [4, 5, 6]

def print_data(data): # <-- Warning: "Shadows 'data' from outer scope
    print data

print_data(data)

Tags: 代码in警告datanamesthis作用域pycharm
3条回答

上面的代码片段没有什么大不了的,但是想象一下一个函数有更多的参数和更多的代码行。然后决定将data参数重命名为yadda,但错过了函数体中使用它的一个位置。。。现在data指的是全局,你开始有奇怪的行为-如果你没有全局名称data,你会有一个更明显的NameError

还要记住,在Python中,一切都是对象(包括模块、类和函数),因此函数、模块或类没有不同的名称空间。另一种情况是在模块顶部导入函数foo,并在函数体的某个地方使用它。然后向函数中添加一个新参数,并将其命名为-bad luck-foo

最后,内置函数和类型也位于同一名称空间中,并且可以以相同的方式进行隐藏

如果您有短函数、良好的命名和良好的单元测试覆盖率,那么这些都不是什么大问题,但是,有时候您必须维护不太完美的代码,并且被警告这些可能的问题可能会有所帮助

在某些情况下,一个好的解决方法可能是将变量和代码移动到另一个函数:

def print_data(data):
    print data

def main():
    data = [4, 5, 6]
    print_data(data)

main()

The currently most up-voted and accepted answer这里的大多数答案都没有抓住要点

不管函数有多长,也不管变量的名称如何(希望尽量减少潜在的名称冲突)

函数的局部变量或其参数恰好在全局范围内共享一个名称,这一事实与此完全无关。事实上,无论您如何小心地选择局部变量名,您的函数永远无法预见“我的酷名yadda将来是否也将用作全局变量?”。解决方案是什么?别担心正确的思维方式是将函数设计为只使用签名中参数的输入。这样,您就不需要关心全局范围内(或将要)的内容,然后阴影就不再是问题了

换句话说,阴影问题只在函数需要使用同名局部变量全局变量时才起作用。但是你首先应该避免这样的设计。OP的代码确实有这样的设计问题。只是PyCharm不够聪明,它会发出警告以防万一。因此,为了让PyCharm满意,也为了让我们的代码干净,请参见这个解决方案引用silyevsk's answer以完全删除全局变量

def print_data(data):
    print data

def main():
    data = [4, 5, 6]
    print_data(data)

main()

这是“解决”这个问题的正确方法,通过修复/删除全局内容,而不是调整当前的局部功能

相关问题 更多 >