我正在使用pycharm
,它列出了与代码相关的所有错误/警告。虽然我理解他们中的大多数但我不确定这个" Shadows从外部范围命名xyz"。关于此问题有几篇SO帖子:How bad is shadowing names defined in outer scopes?但是他们似乎正在访问一个全局变量。
就我而言,我的__main__
函数有一些变量名,然后它调用另一个函数sample_func
,它再次使用这些变量名(主要是循环变量名)。我假设因为我在一个不同的函数,这些变量的范围将是本地的,但警告似乎暗示其他。
有什么想法?以下是一些代码供您参考:
def sample_func():
for x in range(1, 5): --> shadows name x from outer scope
print x
if __name__ == "__main__":
for x in range(1, 5):
sample_func()
答案 0 :(得分:13)
当您在sample_func中时,主函数的if分支内的代码实际上在范围内。您可以从变量x
中读取(试一试)。这没关系,因为你并不关心它,所以你有一些选择可以继续前进。
1)禁用pycharm中的阴影警告。老实说,这是最直接的,取决于你是多么有经验的编码器,它可能是最有意义的(如果你相对较新,我不会这样做。)
2)将主代码放入主函数中。这可能是任何生产级代码的最佳解决方案。 Python非常擅长以你想要的方式做事,所以你应该小心不要陷入陷阱。如果您正在构建模块,那么在模块级别拥有大量逻辑可以让您陷入困境。相反,以下内容可能会有所帮助:
def main():
# Note, as of python 2.7 the interpreter became smart enough
# to realize that x is defined in a loop, so printing x on this
# line (prior to the for loop executing) will throw an exception!
# However, if you print x by itself without the for loop it will
# expose that it's still in scope. See https://gist.github.com/nedrocks/fe42a4c3b5d05f1cb61e18c4dabe1e7a
for x in range(1, 5):
sample_func()
if __name__ == '__main__':
main()
3)不要使用您在更广泛的范围内使用的相同变量名称。这很难强制执行,与#1相反。
答案 1 :(得分:10)
警告是关于通过在内部范围重用这些名称而引入的潜在危险。它可能会让你错过一个错误。例如,考虑一下
def sample_func(*args):
smaple = sum(args) # note the misspelling of `sample here`
print(sample * sample)
if __name__ == "__main__":
for sample in range(1, 5):
sample_func()
因为您使用了相同的名称,所以函数内部的拼写错误不会导致错误。
当你的代码非常简单时,你就会逃避这种类型的事情而没有任何后果。但是使用这些"最佳实践"为了避免更复杂的代码出错。
答案 2 :(得分:1)
这只是一个警告,正如链接问题中所解释的那样,它可能会导致问题,但在您的情况下x
是您的函数本地的。由于x
中的if __name__ == "__main__":
位于全局变量中,因此您收到警告。它对函数中的x
没有任何影响,所以我不担心警告。
答案 3 :(得分:0)
我知道这是一个旧线程,这不适合提问者试图找到的问题,但我正在寻找一个答案,为什么PyCharm向我展示了“外部范围的阴影名称”消息在一个复杂的if / elif语句块...
事实证明我在函数的开头大写了一些全局变量名,但在函数中使用了更小的if / elif块。
学校男孩的错误我知道,但是一旦我纠正了这个,PyCharm中的'外部范围的阴影名称'消息消失了,变量停止显示为灰色......
所以我学到的教训是,这个PyCharm消息可能是由变量名中的大写/小写错误这样简单的事情引起的......
我只是在将函数分解为三个函数时才意识到这个问题,看看是否会删除'Shadows ...'错误,因为我认为我有一个缩进问题,这导致了问题!< / p>
这可能会帮助另一位正在挠头的新手,想知道他们为什么会收到这个错误: - )
答案 4 :(得分:0)
我在名为year
的方法中遇到有关参数的警告,但是没有其他变量共享该名称。然后我意识到这是因为行from pyspark.sql.functions import *
导入了year
变量。将其更改为仅导入我们需要的功能即可摆脱警告。