1

このコード スニペットに問題があります。

import optparse
parser = optparse.OptionParser(version=__version__,
    usage="%prog [options] file1 ... host[:dest]",
    description=main.__doc__)
parser.add_option("-c", "--config", help="Specify an alternate config "
    "file.  Default = '%s'" % config_file)
parser.add_option('-l', '--log-level', type="choice",
    choices=LOG_LEVELS.keys(),
    help="Override the default logging level. Choices=%s, Default=%s" %
        (",".join(LOG_LEVELS.keys()), LOG_LEVEL))
parser.add_option("-o", "--overwrite", action="store_true",
    help="If specified, overwrite existing files at destination.  If "
    "not specified, throw an exception if you try to overwrite a file")
parser.add_option('-s', "--speed", action="store_true", \
    help="If specifed, print the data transfer rate for each file "
        "that is uploaded (infers verbose option)")
parser.add_option('-v', '--verbose', action="store_true",
    help="If specified, print every file that is being uploaded and every "
        "directory that is being created")
parser.add_option("-u", "--user", help="The username to use for "
    "authentication.  Not needed if you have set up a config file.")
parser.add_option("-p", "--password", help="The password to use for "
    "authentication.  Not needed if you have set up a config file.")

parser.set_defaults(config=config_file, log_level=LOG_LEVEL)
options, args = parser.parse_args()
print (args)

ご覧のとおり、ヘブライ語の名前付きファイルで実行しているテストの引数を出力すると、出力結果には ['/root/mezeo_sdk/1/\xfa\xe5\xeb\xf0\xe9\xfa \xf2\ xe1\xe5\xe3\xe4.xlsx', 'hostname'] /root/mezeo_sdk/1/"תוכנית עבודה.xlsx" の代わりに

また、スクリプトがファイルをサーバーにアップロードした後の最終結果 (ファイル名が渡された方法) は次のとおりです: http://i.imgur.com/pP6fA.png

ファイル名自体はLinuxソースで適切です。自分のコンピューターにSCPすると問題ないように見えますが、Pythonスクリプトを使用してファイルサーバーに転送することは一度もありません。

また、問題がファイル サーバー側にあるとは考えていません。Web インターフェースを使用してヘブライ語の名前付きファイルをアップロードすれば問題ないからです。

問題は optparse ライブラリの使用にあると思います。

4

2 に答える 2

4

いつものように、Unicode の推奨される読み物から始めましょう。

(非常に小さい) 一言で言えば、Unicode コード ポイントは、1 つの文字を表す抽象的な「もの」です1。プログラマーは、文字列が一度に 1 文字ずつ来ると考えるのが好きなので、これらを使用するのが好きです。残念ながら、文字はメモリの 1 バイトに収まらなければならないということがずっと前に定められていたため、最大で 256 の異なる文字が存在する可能性があります。これは平易な英語では問題ありませんが、それ以外では機能しません。コード ポイントのグローバル リスト (何千ものコード ポイント) があり、すべての可能な文字を保持することを意図していますが、明らかにそれらは 1 バイトに収まりません。

解決策:文字列を構成するコード ポイントの順序付きリストと、バイト シーケンスとしてのエンコードには違いがあります。文字列を扱うときは常に、これらの形式のいずれであるべきかを明確にする必要があります。形式間で変換するには.encode()、コード ポイントのリスト (Unicode 文字列) をバイトのリストとして、バイトをコードのリストに.decode()変換できます。ポイント。そのためには、コード ポイントをバイトに、またはその逆にマッピングする方法、つまりエンコーディングを知る必要があります。

1並べ替え。


よし、これで邪魔にならないので、あなたが持っているものを見てみましょう。(生の) 文字列を指定しました -- 一連のバイト:

\xfa\xe5\xeb\xf0\xe9\xfa \xf2\xe1\xe5\xe3\xe4

あなたがエンコーディングしたいもの

תוכנית עבודה

少しグーグルで調べると、Windows-1255エンコーディングを使用していることがわかります。これは、上位バイトを使用してヘブライ文字を保持する ASCII の拡張です。Unicode は通常のデータを表すため、文字列を Unicode にする必要があります。したがって、decodeエンコーディングを使用して、バイトのシーケンスを取得する必要があり"Windows-1255"ます。

>>> s
'\xfa\xe5\xeb\xf0\xe9\xfa \xf2\xe1\xe5\xe3\xe4'
>>> s.decode("Windows-1255")
u'\u05ea\u05d5\u05db\u05e0\u05d9\u05ea \u05e2\u05d1\u05d5\u05d3\u05d4'

これで、適切な種類のデータが得られました。次に、データをサーバーに送信する必要があります。これは、通常のエンコード、つまり「UTF-8」でエンコードすることを意味します。

>>> s.decode("Windows-1255").encode("utf-8")
'\xd7\xaa\xd7\x95\xd7\x9b\xd7\xa0\xd7\x99\xd7\xaa \xd7\xa2\xd7\x91\xd7\x95\xd7\x93\xd7\x94'

最後に、サーバーのどこで問題が発生したのか疑問に思うかもしれません。データのエンコーディングを指定しないと、人々は推測する必要があり、企業は失敗する運命にあります。あなたの場合、未加工のバイトをサーバーに送信したように見え、サーバーはそれらを としてデコードしましたlatin-1。latin-1 は ASCII バイトの上位半分をヘブライ文字ではなくアクセント付きの英語の文字に使用するため、奇妙なアクセント付きの文字が表示されます。

話の教訓: Unicode を理解しよう!

于 2012-04-19T07:34:36.637 に答える
3

リストのrepr()を出力します。文字列を印刷すると、ターミナルエミュレータで正しくレンダリングされるはずです。

あなたのimgurリンクに関しては、それがウェブページに表示されているものである場合、あなたはhtmlで正しいエンコーディングを設定する必要があります。

>>> a=['/root/mezeo_sdk/1/\xfa\xe5\xeb\xf0\xe9\xfa \xf2\xe1\xe5\xe3\xe4.xlsx', 'hostname']
>>> print a[0].decode('windows-1255')
/root/mezeo_sdk/1/תוכנית עבודה.xlsx
于 2012-04-19T07:23:08.390 に答える