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

我只是切换到Pycharm,我很高兴所有的警告和提示,它使我改善我的代码。 除了这个我不明白的那个:

This inspection detects shadowing names defined in outer scopes.

我知道从外部范围访问variables是不好的做法,但是影响外部范围的问题是什么?

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

 data = [4, 5, 6] def print_data(data): # <-- Warning: "Shadows 'data' from outer scope print data print_data(data) 

上面的代码片段没什么大不了的,但想象一个带有更多参数和更多代码行的函数。 然后,你决定重命名你的data参数为yadda但错过其中一个地方,它在函数的身体…现在data指的是全球性的,你开始有奇怪的行为 – 你会有一个更明显的NameError if您没有全球名称data

还要记住,在Python中,一切都是一个对象(包括模块,类和函数),所以对于函数,模块或类没有独特的名称空间。 另一种情况是,你在你的模块的顶部导入函数foo ,并在函数体的某个地方使用它。 然后你添加一个新的参数给你的函数,并命名为 – 运气不好 – foo

最后,内置的函数和types也存在于相同的命名空间中,并且可以以相同的方式进行映射。

如果你的function很短,命名方式很好,unit testing的覆盖面不错,但是有时候你不得不维护一些不太完美的代码,并且要注意这些可能的问题。

目前最受欢迎的答案和大多数答案都没有涉及到这一点。

不pipe你的function是多长时间,或者你如何描述性地描述你的variables(希望尽量减less潜在的名称冲突的可能性)。

事实上,你的函数的局部variables或其参数碰巧在全局范围内共享一个名字是完全不相关的。 而事实上,无论你select多么谨慎的本地variables名,你的函数永远都不可能预见到“我的酷名yadda是否也将在未来被用作全局variables?”。 解决scheme? 根本不用担心! 正确的思维方式是devise你的函数来消费来自并且仅仅来自其签名参数的input,这样你就不需要关心全球范围内的(或者将要)什么,然后阴影就不会成为问题。

换句话说,影子问题只在你的函数需要使用同名的局部variables和全局variables时才起作用。 但是你应该首先避免这样的devise。 OP的代码并不是真的有这样的devise问题。 只是PyCharm不够聪明,为了以防万一。 所以,为了使PyCharm高兴,也使我们的代码清洁,看到这个解决scheme引用silyevsk的答案完全删除全局variables。

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

这是“解决”这个问题的正确方法,通过修改/删除全局的东西,而不是调整当前的本地function。

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

 def print_data(data): print data def main(): data = [4, 5, 6] print_data(data) main() 
 data = [4, 5, 6] #your global variable def print_data(data): # <-- Pass in a parameter called "data" print data # <-- Note: You can access global variable inside your function, BUT for now, which is which? the parameter or the global variable? Confused, huh? print_data(data) 

这取决于function是多久。 函数越长,将来有人修改它的机会越大,写出的data就意味着它是全局的。 事实上,这意味着当地的,但由于function如此之长,他们不知道有一个地方有这个名字。

对于您的示例function,我认为影响全球并不糟糕。

做这个:

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