2

結果コードを設定する礼儀を持たない関数の出力を理解しようとしています。多くの場合、別の変換ステータス メッセージの途中で、stderr ストリームに混在する "error:" 文字列によって失敗したことがわかります。

次のリスト内包表記は機能しますが、「エラー:」文字列を 2 回スキャンします。実際のエラー行を再スキャンしているだけなので、問題なく動作しますが、シングル スキャンの使い方がわからないのが気になります。作業コードは次のとおりです。

errors = [e[e.find('error:'):] for e in err.splitlines() if 'error:' in e]

単純化する明白な (そして間違った) 方法は、「検索」結果を保存することです

errors = [e[i:] for i in e.find('error:') if i != -1 for e in err.splitlines()]

ただし、「UnboundLocalError: ローカル変数 'e' が割り当て前に参照されました」というメッセージが表示されます。内包表記の for をやみくもに逆にすることも失敗します。これはどのように行われますか?

ありがとう。ケント

4

3 に答える 3

3

'error'ジェネレーター式の中にチェックを配置できます。

[e[i:] for i,e in
 ((e.find('error:'),e) for e in err.splitlines())
 if i != -1]

あなたがしたことは、ネストされた内包表記を作成することでありe、2 番目のループの前に変数を使用することで、UnboundLocalError を取得しました。

ところで、正規表現を使用して、この理解を回避することもできます。

re.findall('error:(.*)', err)

行を分割する必要もありません。

完全なエラー(error:パーツを含む)の場合、これは機能します:

re.findall('error:.*', err)
于 2012-06-26T15:05:31.760 に答える
2

通常のループでジェネレーターを使用して、状態が必要なこの種のタスクを実行します。

def errsplit(err):
    for e in err.splitlines():
        errindex = e.find('error:')
        if errindex > -1: yield e[errindex:]

これをリストとして必要な場合は、 を実行してくださいlist(errsplit(err))

リスト内包表記は、保存された状態を扱うことを意図したものではなく、保存された状態を使用しようとすると扱いにくくなる可能性があります。

とはいえ、@JBernardo が示唆するように、正規表現の方が良いかもしれないことに注意してください。

于 2012-06-26T15:08:51.773 に答える
0

JBernardo のソリューションを試してみましたが、実際にうまくいったのは次のとおりです。

[errstr[i:] for i,errstr in
 ((e.find('error:'), e) for e in err.splitlines())
 if i != -1]
于 2012-06-26T15:21:58.603 に答える