在`main`模块中运行时的NameError

时间:2017-10-22 08:00:48

标签: python-3.x

我试图在文件中递归获取所有.md文件。为了完成它,我定义了一个在main模块中运行的递归函数。

代码:

import os
def walk(dirname):
    for name in os.listdir(dirname):
        path = os.path.join(dirname, name)
        if os.path.isfile(path):
            if '.md' in path:
                path_list.append(path)
        else:
            walk(path)
    return path_list
def main():
    dir = '/Users/Documents/Diary'
    path_list = []
    path = walk(dir)

if __name__ == '__main__':
    main()

运行时,会报告:

NameError: name 'path_list' is not defined

但是,如果在没有main()的情况下运行,则可以正常运行:

In [80]: path_list = []
    ...: def walk(dirname):
    ...:     for name in os.listdir(dirname):
    ...:         path = os.path.join(dirname, name)
    ...:         if os.path.isfile(path):
    ...:             if '.md' in path:
    ...:                 path_list.append(path)
    ...:         else:
    ...:             walk(path)
    ...:     return path_list

输出:

dir = '/Users/Documents/Diary'
walk(dir)
Out[81]:
['/Users/Documents/Diary/py4.1.If_statements.md',
 '/Users/Documents/Diary/pyName_and_object:.md',
 ...]

我不知道这个错误是什么。

3 个答案:

答案 0 :(得分:1)

您的第二个选项将path_list声明为全局变量,因此它在所有函数中都是已知的。

您也可以在walk()函数中声明它,这是唯一需要它的地方。但是,正如所评论的那样,由于该函数是递归调用的,因此每次都会重置列表,而不是聚合结果。

点击“Notes on Python variable scope”了解更多信息。

  

全局变量可在函数内部和外部访问   局部变量只能在函数内部访问   如果我在一个与全局变量同名的函数中设置变量,我实际上是在创建一个新的局部变量。

答案 1 :(得分:1)

这里的问题是对象的范围。

当您创建main()函数时,您在path_list的本地范围内声明main()。因此walk()功能无法使用它。

您必须将path_list作为参数传递给全局,或者将其全局声明为后者以使其可用。截至目前,path_list超出了walk()的范围。

答案 2 :(得分:0)

您需要在path_list函数中声明walk,因为它是在其上运行的函数。您收到错误,因为您在该函数中没有预先声明任何path_list

此外,您不需要在main函数中定义任何path_list,因为它不对它进行操作而不需要它。

当您全局声明它时,它可用于所有函数,甚至是walk函数。它使用该全局变量,您不会收到任何错误。