1

私は現在、Javaファイルを検索し、特定のキーワードが使用された回数に関する情報を出力する一連のサブディレクトリをループする単純なPythonプログラムを作成しようとしています。私はこれをほとんどの部分で機能させることができました。私が抱えている問題は、上位ディレクトリに関する全体的な情報を出力することです。たとえば、現在の出力は次のとおりです。

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 に答える