0

このスクリプトをまとめて、特定のファイル全体を検索できるようにしました。これは grep に似た機能を実行しますが、grep が提供するものよりももう少し具体的なものが必要だったので、Python を試しています。

3 つのメソッドを持つ 1 つのクラスがあります。2 番目の方法listOccurrencesOfToDoInFile(30 行目) は失敗します。これは小さなスクリプトですが、Python ではタブが重要なので、Gist にまとめました。私の一見有効なPythonが無効である理由を誰か教えてもらえますか?

import os
import keyword
import sys


class Toodles:

    def walkAndList(directory):
        for dirname, dirnames, filenames in os.walk(directory):

            # print path to all filenames.
            for filename in filenames:
                workingFilename = os.path.join(dirname, filename)
                if(isSourceFile(filename)):
                    listOccurrencesOfToDoInFile(filename)

            # Advanced usage:
            # editing the 'dirnames' list will stop os.walk() from recursing into there.
            if '.git' in dirnames:
                # don't go into any .git directories.
                dirnames.remove('.git')

            for dirs in dirnames:
                self.walkAndList(os.path.join(dirname, dirs)


    #   Find occurences of "todo" and "fixme" in a file
    #   If we find such an occurence, print the filename, 
    #   the line number, and the line itself.
    def listOccurrencesOfToDoInFile(aFileName):
        input = open(aFileName)
        currentLine = 1
        for (line in input):
            line = line.lower()
            currentLine = currentLine + 1
            needle = "todo"
            if (needle in line):
                sys.stdout.write(aFileName + " (" + str(currentLine) + ")" + line)

    #Todo: add a comment
    def isSourceFile(self, name):
        fileName, fileExtension = os.path.splitext(name)
        if (".m" in fileExtension or ".c" in fileExtension or ".h" in fileExtension):
            return True
        return False


if ( __name__ == "__main__") {
    a = Toodles()
    a.walkAndList('.')
}   
4

1 に答える 1

3

閉じ括弧がありません:

 self.walkAndList(os.path.join(dirname, dirs)

開き括弧は 2 つあるが、閉じ括弧は 1 つしかないことに注意してください。

次の問題は、中括弧をさらに下に使用していることです。

if ( __name__ == "__main__") {
    a = Toodles()
    a.walkAndList('.')
}

これは Python であり、C、Java、Javascript ではありません。中かっこを削除し、コロンを使用します。

if __name__ == "__main__":
    a = Toodles()
    a.walkAndList('.')

for次に、正当な Python ではない方法でステートメントで括弧を使用しています。

for (line in input):

これらの括弧を削除します:

for line in input:

self次の問題は、2 つのメソッドを定義していないことです。

def walkAndList(directory):

def listOccurrencesOfToDoInFile(aFileName):

self最初のパラメーターとして追加します。

def walkAndList(self, directory):
# ...
def listOccurrencesOfToDoInFile(self, aFileName):

次に、メソッドToodles.isSourceFile()とメソッドをグローバルとして扱います。現在のインスタンスでメソッドとして呼び出すには、これらの前Toodles.listOccurrencesOfToDoInFile()に追加する必要があります。self.

if(isSourceFile(filename)):
    listOccurrencesOfToDoInFile(filename)

次のようにする必要があります (冗長な括弧なし):

if self.isSourceFile(filename):
    self.listOccurrencesOfToDoInFile(filename)

次に、代わりfilenameに必要な場所 (パスを含む) を参照します (パスがありません)。workingFilename

self.listOccurrencesOfToDoInFile(workingFilename)

または、それらのファイルを開くときにエラーが発生します。

次に、ファイル拡張子のテストに欠陥があります。または.endswith()などのファイルの一致を防ぐために使用します。さらに、最初に何かが であるかどうかをテストしてから、個別にorを返すように要求する必要はありません。ブール値のテストを直接返すことができます:.csh.hifTrueTrueFalse

def isSourceFile(self, name):
    return name.endswith(('.m', '.c', '.h'))

シーケンスをループするときにカウントするときは、enumerate()関数を使用してカウンターを生成します。

for currentLine, line in enumerate(input, 1):
    line = line.lower()

行を 1 から数えます。

os.walk() すでにサブディレクトリをトラバースしていることに注意してください。再帰する必要はありませ。次の行を削除して、再帰を削除します。

for dirs in dirnames:
    self.walkAndList(os.path.join(dirname, dirs))

さらにいくつかの改善 (with開いているファイルを再び閉じる、ループのneedle に設定する、早期にフィルター処理する、文字列の書式設定を使用する、小文字ではなく元の行を書き出す) を使用すると、完全なスクリプトは次のようになります。

import os
import sys


class Toodles(object):
    def walkAndList(self, directory):
        for dirname, dirnames, filenames in os.walk(directory):
            for filename in filenames:
                if self.isSourceFile(filename):
                    workingFilename = os.path.join(dirname, filename)
                    self.listOccurrencesOfToDoInFile(workingFilename)

            # Advanced usage:
            # editing the 'dirnames' list will stop os.walk() from recursing into there.
            if '.git' in dirnames:
                # don't go into any .git directories.
                dirnames.remove('.git')

    #   Find occurences of "todo" and "fixme" in a file
    #   If we find such an occurence, print the filename,
    #   the line number, and the line itself.
    def listOccurrencesOfToDoInFile(self, aFileName):
        needle = "todo"
        with open(aFileName) as input:
            for currentLine, line in enumerate(input, 1):
                if needle in line.lower():
                    sys.stdout.write('{}: ({}){}'.format(aFileName, currentLine, line))

    #Todo: add a comment
    def isSourceFile(self, name):
        return name.endswith(('.m', '.c', '.h'))


if __name__ == "__main__":
    a = Toodles()
    a.walkAndList('.')
于 2013-06-12T15:24:34.987 に答える