Python脚本错误

时间:2013-04-03 23:30:45

标签: python

我有这个脚本,我毫无疑问是有缺陷的:

import fnmatch, os, sys
def findit (rootdir, find, pattern):
    for folder, dirs, files in os.walk(rootdir):
        print (folder)
    for filename in fnmatch.filter(files,pattern):          
        with open(filename) as f:
            s = f.read()
            f.close()
            if find in s :                  
                print(filename)

findit(sys.argv[1], sys.argv[2], sys.argv[3])

当我运行它时,我得到Errno2, no such file or directory。但该文件存在。例如,如果我执行它:findit.py c:\python "folder" *.py它将正常工作,列出包含单词“folder”的所有* .py文件。但是如果我去findit.py c:\php\projects1 "include" *.php

作为示例,我得到[Errno2] no such file or directory: 'About.php'(例如)。但是About.php存在。我不明白它在做什么,或者我做错了什么。

2 个答案:

答案 0 :(得分:2)

如果您查看os.walk的任何示例,您会看到它们都os.path.join(root, name)。你也需要这样做。

为什么呢?引用文档:

  

filenames是dirpath中非目录文件的名称列表。请注意,列表中的名称不包含路径组件。要获取dirpath中文件或目录的完整路径(以top开头),请执行os.path.join(dirpath, name)

如果您只使用文件名作为路径,它将在当前工作目录中查找同名文件。如果没有此类文件,您将获得FileNotFoundError。如果这样的文件,您将打开并读取错误的文件。只有当你碰巧在当前工作目录中查看它才有效。


您的代码中还存在另一个主要问题:os.walk递归遍历目录树,查找给定top目录中的所有文件,或top的任何子目录,或任何子目录......依此类推,每个目录都会产生一次。但你没有做任何有用的事情(除了打印文件夹)。相反,你要等到它完成,然后使用files来自它最后到达的目录。

如果您只想直接在目录中获取文件的详细列表,请使用os.listdir,而不是os.walk。 (或者可以使用glob.glob代替明确列出所有内容,然后使用fnmatch进行过滤。)

另一方面,如果你想走树,你必须将第二个for循环移到第一个循环中。


您还遇到了一个小问题:您在f.close()内拨打with open(…) as f:,这导致f被关闭两次。这保证是完全无害的(至少在2.5+,包括3.x),但它仍然是一个坏主意。


把它放在一起,这是你的代码的工作版本:

def findit (rootdir, find, pattern):
    for folder, dirs, files in os.walk(rootdir):
        print (folder)
        for filename in fnmatch.filter(files,pattern):
            pathname = os.path.join(folder, filename)
            with open(pathname) as f:
                s = f.read()
                if find in s:
                    print(pathname)

答案 1 :(得分:1)

您正在使用相对文件名。但是您当前的目录不包含该文件。而且你不想在那里搜索。使用os.path.join(文件夹,文件名)来创建绝对路径。

相关问题