代码之家  ›  专栏  ›  技术社区  ›  GoldenMan

如何正确命名变量以避免Python中出现“来自外部作用域的阴影名称”之类的警告

  •  5
  • GoldenMan  · 技术社区  · 6 年前

    我在python程序中使用PyCharm,并编写了以下代码:

    def get_files_name():
        root_dir = "/Volumes/NO NAME/"
        for root, ds, fs in os.walk(root_dir):
            for f in fs:
                print(os.path.join(root_dir, f))
    
    
    get_files_name()
    for root, ds, fs in os.walk(other_dir):
        pass
    

    因此,我得到了一条警告文本,如“Shadows name‘ds’from outer scope”。 我知道作用域的效果,但我仍然希望使用相同的代码格式,如“for root,ds,fs in….”在范围内或范围外。

    我已经搜索了PEP8,但我仍然不知道如何规范地命名函数中的变量。

    你能给我一些建议吗?

    3 回复  |  直到 6 年前
        1
  •  3
  •   Martijn Pieters    6 年前

    一般来说:忽略警告即可。这只是一个警告,不是一个错误。您可以使用碰巧匹配的全局名称和本地名称。

    然而,我不会 os.walk() 在全局范围内调用 无论如何 . 我宁愿把它也放到一个函数中,它有一个令人高兴的副作用,即您使用的名称不再是全局名称。

    例如,您可以使用 main() 功能:

    def main():
        get_files_name()
        for root, ds, fs in os.walk(other_dir):
            pass
    
    if __name__ == '__main__':
        main()
    

    一般来说,您不希望留下循环名称,如 root, ds, fs 作为模块中的全局成员。这些是实现细节,不应成为模块公共API的一部分。如果你 使用 for 在全局范围内这样循环,使用 _ 名称上的单下划线前缀,并考虑在循环后使用 del :

    for _root, _ds, _fs in os.walk(other_dir):
        # do something with the files or directories
    
    # clean variables for the loop that are not part of the API
    del _root, _ds, _fs
    
        2
  •  1
  •   Alex Delarge    6 年前

    如果您的名字重复出现,请使用“\u”以避免此类警告。这是一种常见的做法。

    def get_files_name():
        root_dir = "/Volumes/NO NAME/"
        for root, _ds, fs in os.walk(root_dir):
            for f in fs:
                print(os.path.join(root_dir, f))
    
    get_files_name()
    for root, _ds, fs in os.walk(other_dir):
        pass
    
        3
  •  0
  •   carrdelling    6 年前

    那个警告 shadows name XX from outer scope 这不是PEP8的问题,而是Pycharm的一个实际警告,告诉您以这种方式重用变量名是个坏主意。换句话说,这不是一个代码风格的问题,而是可能在以后的大型程序中带来问题的问题。

    我的建议是,尽可能避免重用变量名。键入以下内容:

    for root_path, directory_name, file_name in os.walk(root_dir):

    不需要太多时间,并且可以避免将来出现不良副作用。

    尽管如此,如果出于任何原因,您确实需要重用变量名并希望消除警告消息,您可以在Pycharm中禁用它(首选项->编辑器->代码样式->检查->从外部作用域隐藏名称)。但这通常是个坏主意。