在外部作用域中定义的阴影名称有多糟?

2024-04-24 09:38:11 发布

您现在位置: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条回答

在某些情况下,一个很好的解决方法是将vars+代码移到另一个函数:

def print_data(data):
    print data

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

main()

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

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

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

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

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

不管你的函数有多长,或者你如何用描述性的方式命名变量(希望尽量减少潜在的名称冲突)。

函数的局部变量或其参数碰巧在全局范围内共享一个名称,这一事实完全不相关。事实上,无论您如何谨慎地选择本地变量名,您的函数都无法预知“我的酷名yadda将来是否也将用作全局变量?”。解决办法?别担心!正确的思路是设计您的函数以使用签名中的参数输入,并且仅使用其参数输入,这样您就不需要关心全局范围内是什么(或将是什么),然后阴影就完全不成问题了。

换句话说,阴影问题只在函数需要使用相同名称的局部变量和全局变量时才重要。但你首先应该避免这样的设计。操作系统的代码并没有这样的设计问题。只是PyCharm不够聪明,它会发出警告以防万一。所以,为了让PyCharm高兴,同时也为了让我们的代码干净,请参阅这个引用silyevsk 's answer的解决方案,以完全删除全局变量。

def print_data(data):
    print data

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

main()

这是“解决”这个问题的正确方法,通过修复/删除全局对象,而不是调整当前的本地函数。

相关问题 更多 >