1

デコレータがどのように機能するのかに興味があったので、ウォーキング パス内に汎用関数を配置するのに機能するかどうかを調べていました。パスの下のスペースで区切られたファイルで整数の最長セグメントを返したいと思いました(そして、この値を返すか、おそらくそれを印刷します)。これは可能ですか?

countL で物事を返そうとしましたが、成功しませんでした。次に、これがどのように機能するかを関数の外に配置した場合に興味がありました。デコレータは印刷専用ですか、それともデコレータから戻ってこの例を適切に動作させることができますか??

def walkPath(fn):
    def wrapper(*args, **kwargs):
        outside = None
        for dirname, dirnames, filenames in os.walk(args[0]):
            for filename in filenames:
                fn(filename, dirname, outside, *args, **kwargs)
    return wrapper

@walkPath
def countL(filename, dirname, outside, path, extension = '.wrd'):
    if (filename[-4:]  == extension):
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            if (int(temp[1]) - int(temp[0]) > longest):                
                outside = int(temp[1]) - int(temp[0])

これは、私がデコレータなしで何をしていたかを説明しており、同じ機能を得ることができるかどうかを確認していましたが、それを汎用にしています。これは、一連のファイルの中で必ずしも最長の単語ではなく、たとえばファイル名に「s」という単語が含まれる一連のファイルである可能性があることを意味します。外部変数を最長で適切に処理する方法、またはそれがデコレータで可能かどうかがわからないだけです。

def countLength(path, extension = '.wrd'):
    longest = 0
    for dirname, dirnames, filenames in os.walk(path):
        for filename in filenames:
            if (filename[-4:]  == extension):
                with open(os.path.join(dirname, filename), 'r') as input:
                    data = input.readlines()
                for i in range(len(data)):
                    temp = data[i].split()
                    if (int(temp[1]) - int(temp[0]) > longest):
                        longest = int(temp[1]) - int(temp[0])
    return longest
4

2 に答える 2

1

問題は、外側のループとその本体に分割しようとしているが、ループ内にlongest数値を比較するためのローカル変数 ( ) があることです。したがって、内部関数で結果を集計する必要があります。つまり、 walkPath ループは へのすべての呼び出しの結果を保存し、次の呼び出しに渡す必要があるため、内でfn比較を行うことができます。最後に、最後の呼び出しが返したものを吐き出す必要があります。これがあなたがやろうとしていたことだと思います。また、何もしなかったため、 から引数を削除しました。あなたの例は次のように動作するはずです: fnoutsidepathcountL

def walkPath(fn):
    def wrapper(outside, *args, **kwargs):
        for dirname, dirnames, filenames in os.walk(args[0]):
            for filename in filenames:
                outside = fn(outside, filename, dirname, *args, **kwargs)
        return outside
    return wrapper

@walkPath
def countL(outside, filename, dirname, extension = '.wrd'):
    if (filename[-4:]  == extension):
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            if (int(temp[1]) - int(temp[0]) > outside):                
                outside = int(temp[1]) - int(temp[0])
    return outside

次に、のようなものを呼び出す必要がありますcountL(0)

于 2012-05-11T05:14:26.783 に答える
0

集計する場所とデータを返す方法を決定する必要があります。私はこのようにします:

def walkPath(fn):
    def wrapper(walkroot, *args, **kwargs):
        for dirname, dirnames, filenames in os.walk(walkroot):
            for filename in filenames:
                res = fn(filename, dirname, *args, **kwargs)
                if res is not None: yield res
    return wrapper

@walkPath
def countL(filename, dirname, extension='.wrd'):
    if os.path.splitext(filename)[1] == extension:
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            return int(temp[1]) - int(temp[0])

の呼び出し元はwalkPath()、各ファイルから「デルタ値」を生成するジェネレーターを取得します。したがって、最大値を簡単に見つけることができますmax(walkPath(...))

その上、拡張子の比較を次のように変更しました

if os.path.splitext(filename)[1] == extension:

import osどこかにあなたを提供しました。


止まる。コードを読み直した後、私は尋ねなければなりません:

ファイルに複数の値のペアが含まれている可能性がありますか? もしそうならcountL()、ジェネレータを返さなければなりません。

@walkPath
def countL(filename, dirname, extension='.wrd'):
    if os.path.splitext(filename)[1] == extension:
        with open(os.path.join(dirname, filename), 'r') as input:
            data = input.readlines()
        for i in range(len(data)):
            temp = data[i].split()
            yield int(temp[1]) - int(temp[0])

デコレートされcountL()た関数は、ジェネレーターを生成するジェネレーターを返します。

max(value for filegen in countL(...) for value in filegen)

または、次のように変更walkPath()することもできます

def walkPath(fn):
    def wrapper(walkroot, *args, **kwargs):
        for dirname, dirnames, filenames in os.walk(walkroot):
            for filename in filenames:
                for item in fn(filename, dirname, *args, **kwargs):
                    yield item
    return wrapper

への各呼び出しのアイテムを生成するようにしfn()ます。するだけで十分ではない

max(countL(...))

また。

于 2012-05-11T05:26:12.563 に答える