外部作用域中定义的阴影名称有多糟?
我只是切换到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()