1
$ ./a.py b.xml

これで結構です。a.py はファイルを読み取り、何かを出力します。

a.py は次のように引数を読み取ります

# Each argument is a file
args = sys.argv[1:]

# Loop on files
for filename in args :

    # Open the file
    file = open(filename)

他のスクリプトにパイプアウトしたい。

$ ./a.py b.xml | grep '1)'

これにより、python エラーが発生します。


これも失敗

$ x=$(./a.py b.xml); echo $x...

| などのシェルスクリプト構文を解釈しないように Python に指示する方法 $() `` ?


エラーは

Traceback (most recent call last):
  File "./flattenXml.py", line 135, in <module>
    process(file, prefix)
  File "./flattenXml.py", line 116, in process
    linearize(root, prefix + "//" + removeNS(root.tag))
  File "./flattenXml.py", line 104, in linearize
    linearize(childEl, path + '/' + numberedTag)
  File "./flattenXml.py", line 104, in linearize
    linearize(childEl, path + '/' + numberedTag)
  File "./flattenXml.py", line 104, in linearize
    linearize(childEl, path + '/' + numberedTag)
  File "./flattenXml.py", line 104, in linearize
    linearize(childEl, path + '/' + numberedTag)
  File "./flattenXml.py", line 104, in linearize
    linearize(childEl, path + '/' + numberedTag)
  File "./flattenXml.py", line 104, in linearize
    linearize(childEl, path + '/' + numberedTag)
  File "./flattenXml.py", line 83, in linearize
    print path + "/@" + removeNS(name) + "=" + val
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 106: ordinal not in range(128)

Python スクリプトはPython レシピからのものです。

4

1 に答える 1

1

問題は、ドキュメントに ascii 出力ストリームに出力できない非 ascii 文字が含まれていることです。

内部的には、python は任意の unicode 文字を処理できますが、その文字がシリアル化されると、python は正しいビットを書き込むことができるように、使用する表現 (utf-8、utf-16、または無数の国際文字エンコーディングのいずれか) を知る必要があります。

コンソールで実行すると、python は端末のエンコーディングを取得し (私の場合は en_US.UTF-8)、sys.stdout のエンコーダを適切にセットアップできます。stdout を別のプログラムにパイプしたり、stdout をファイルにリダイレクトしたりするとき、python は何をすべきかわからず、デフォルトで sys.stdout の ascii エンコーダーを設定します。

コンソールで実行すると、エンコーダーは通常、文字を端末に適したビットに変換する方法を認識しており、見栄えの良い表示が得られます。パイプされると、ASCII エンコーダーは文字を処理できず、エラーがスローされます。

1 つの解決策は、stdout に書き込む前にすべてを utf-8 にエンコードすることです。

import sys
encoding = sys.stdout.encoding or 'utf-8'

...
print (path + "/@" + removeNS(name) + "=" + val).encode(encoding)

ここで、utf-8 エンコーダーは、sys.stdout にまだ存在する ascii エンコーダーを通過して反対側に到達する文字列を送信します。反対側のプログラムがutf-8を処理できるかどうかは未解決の問題です。

于 2013-10-03T21:00:15.813 に答える