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

新手上路,请多包涵

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

此检查检测在外部范围中定义的隐藏名称。

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

这是一个示例,其中 PyCharm 向我发出警告消息:

 data = [4, 5, 6]

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

print_data(data)

原文由 Framester 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 5.7k
2 个回答

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

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

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

如果您有简短的功能、良好的命名和不错的单元测试覆盖率,那么这一切都不是什么大问题,但是有时您必须维护不完美的代码,并且被警告此类可能的问题可能会有所帮助。

原文由 bruno desthuilliers 发布,翻译遵循 CC BY-SA 4.0 许可协议

目前投票最多和接受最多的 答案和这里的大多数答案都没有抓住要点。

无论您的函数有多长,或者您如何描述性地命名您的变量(希望尽量减少潜在的名称冲突的机会)都没有关系。

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

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

 def print_data(data):
    print data

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

main()

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

原文由 RayLuo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏