1

我目前正在尝试编写一个简单的 python 程序,该程序循环遍历一堆子目录,查找 java 文件并打印有关某些关键字使用次数的一些信息。我已经设法让这个大部分工作。我遇到的问题是打印有关更高目录的整体信息,例如,我当前的输出如下:

testcases/part1/testcase2/root_dir:
    0   bytes     0   public     0   private     0   try     0   catch
testcases/part1/testcase2/root_dir/folder1:
    12586   bytes     19   public     7   private     8   try     22   catch
testcases/part1/testcase2/root_dir/folder1/folder5:
    7609   bytes     9   public     2   private     7   try     11   catch
testcases/part1/testcase2/root_dir/folder4:
    0   bytes     0   public     0   private     0   try     0   catch
testcases/part1/testcase2/root_dir/folder4/folder2:
    7211   bytes     9   public     2   private     4   try     9   catch
testcases/part1/testcase2/root_dir/folder4/folder3:
    0   bytes     0   public     0   private     0   try     0   catch

我希望输出为:

testcases/part1/testcase2/root_dir :
    27406  bytes    37  public    11  private    19  try    42  catch
testcases/part1/testcase2/root_dir/folder1 :
    20195  bytes    28  public     9  private    15  try     33  catch
testcases/part1/testcase2/root_dir/folder1/folder5 :
    7609  bytes     9  public     2  private     7  try      11  catch
testcases/part1/testcase2/root_dir/folder4 :
    7211  bytes     9  public     2  private     4  try     9  catch
testcases/part1/testcase2/root_dir/folder4/folder2 :
    7211  bytes     9  public     2  private     4  try     9  catch
testcases/part1/testcase2/root_dir/folder4/folder3 :
    0  bytes        0  public     0  private     0  try     0  catch

如您所见,较低的子目录直接将信息提供给较高的子目录。这是我遇到的问题。如何有效地实现这一点。我考虑过将每个打印内容存储为列表中的字符串,然后在最后打印所有内容,但我认为这不适用于多个子目录,例如提供的示例。到目前为止,这是我的代码:

def lsJava(path):

print()

for dirname, dirnames, filenames in os.walk(path):

    size = 0
    public = 0
    private = 0
    tryCount = 0
    catch = 0

    #Get stats by current directory.
    tempStats = os.stat(dirname)

    #Print current directory information

    print(dirname + ":")

    #Print files of directory.
    for filename in filenames:
        if(filename.endswith(".java")):
            fileTempStats = os.stat(dirname + "/" + filename)
            size += fileTempStats[6]
            tempFile = open(dirname + "/" + filename)
            tempString = tempFile.read()
            tempString = removeComments(tempString)
            public += tempString.count("public", 0, len(tempString))
            private += tempString.count("private", 0, len(tempString))
            tryCount += tempString.count("try", 0, len(tempString))
            catch += tempString.count("catch", 0, len(tempString))

    print("       ", size, "  bytes    ", public, "  public    ",
        private, "  private    ", tryCount, "  try    ", catch,
        "  catch")

removeComments 函数使用正则表达式模式简单地从 java 文件中删除所有注释。感谢您提前提供任何帮助。

编辑:

在 for 循环的开头添加了以下代码:

    current_dirpath = dirname

    if( dirname != current_dirpath):
        size = 0
        public = 0
        private = 0
        tryCount = 0
        catch = 0

现在的输出如下:

testcases/part1/testcase2/root_dir/folder1/folder5:
    7609   bytes     9   public     2   private     7   try     11   catch
testcases/part1/testcase2/root_dir/folder1:
    20195   bytes     28   public     9   private     15   try     33   catch
testcases/part1/testcase2/root_dir/folder4/folder2:
    27406   bytes     37   public     11   private     19   try     42   catch
testcases/part1/testcase2/root_dir/folder4/folder3:
    27406   bytes     37   public     11   private     19   try     42   catch
testcases/part1/testcase2/root_dir/folder4:
    27406   bytes     37   public     11   private     19   try     42   catch
testcases/part1/testcase2/root_dir:
    27406   bytes     37   public     11   private     19   try     42   catch
4

2 回答 2

2

os.walk()接受一个可选topdown参数。如果您使用os.walk(path, topdown=False)它将自下而上遍历目录。

当您第一次启动循环时,将元组的第一个元素(dirpath)保存为变量,如current_dirpath. 当您继续循环时,您可以保持该目录中文件大小的总和。然后只需添加一个像 一样的检查if dirpath != current_dirpath,此时您知道您已经上升了一个目录级别,并且可以重置总数。

于 2012-12-07T17:07:38.620 回答
1

我不相信你可以用一个计数器来做到这一点,即使是自下而上:如果目录 A 有子目录 B 和 C,当你完成 B 后,你需要在进入 C 之前将计数器归零;但是到了做A的时候,你需要把B和C的尺寸相加(但是B的计数早就没有了)。

与其维护单个计数器,不如建立一个字典,将每个目录(键)映射到相关的计数(在元组或其他形式中)。当您迭代(自下而上)时,无论何时您准备好打印一个目录的输出,您都可以查找它的所有子目录(从dirname返回的参数中os.walk())并将它们的计数加在一起。

由于您不丢弃数据,因此可以扩展此方法以维护单独的深度计数和浅计数,以便在扫描结束时您可以按浅计数对目录进行排序,报告 10 个最大计数等。

于 2012-12-07T17:53:21.817 回答