阴影从外部范围命名xyz

The*_*rer 18 python pycharm python-2.7

我正在使用pycharm它,它列出了与代码相关的所有错误/警告.虽然我理解他们中的大部分但我不确定这个"Shadows从外部范围命名xyz".关于此问题有一些SO帖子:在外部范围中定义的阴影名称有多糟糕?但后来他们似乎正在访问一个全局变量.

在我的例子中,我的__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()
Run Code Online (Sandbox Code Playgroud)

meh*_*guh 14

警告是关于通过在内部范围重用这些名称而引入的潜在危险.它可能会让你错过一个错误.例如,考虑一下

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()
Run Code Online (Sandbox Code Playgroud)

因为您使用了相同的名称,所以函数内部的拼写错误不会导致错误.

当你的代码非常简单时,你就会逃脱这种类型的事情而没有任何后果.但是,使用这些"最佳实践"以避免更复杂的代码出错是件好事.

  • @TheWanderer 是的,通过定义“main”函数,他改变了原始定义的范围,以便它们不再冲突。 (3认同)
  • 这是一个很好的例子。然而,无论您尝试多少,您总会有一些常见的变量名称。您认为确定变量名称范围的更好方法是什么?正如 Ned 所建议的,使用另一个名为“main()”的函数是否会限制变量的范围? (2认同)

Ned*_*son 13

当您在sample_func中时,main函数的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()
Run Code Online (Sandbox Code Playgroud)

3)不要使用您在更广泛的范围内使用的相同变量名称.这很难强制执行,与#1相反.