4

ほぼ同一の 2 つのテキスト ファイル (MacVim で作成されたプレーン テキスト) がある場合、それらを Python で変数に読み込むと、異なる結果が得られます。これがなぜなのか、どのようにして一貫した動作を生成できるのかを知りたいです。

たとえば、f1.txt は次のようになります。

This isn't a great example, but it works.

f2.txt は次のようになります。

This isn't a great example, but it wasn't meant to be. 
"But doesn't it demonstrate the problem?," she said.

これらのファイルを読み込むときは、次のようなものを使用します。

f = open("f1.txt","r")
x = f.read()

コンソールで変数を見ると、次のようになります。f1.txt:

>>> x
"This isn't a great example, but it works.\n\n"

f2.txt:

>>> y
'This isn\'t a great example, but it wasn\'t meant to be. \n"But doesn\'t it demonstrate the problem?," she said.\n\n'

言い換えれば、f1 はエスケープされた改行だけで入りますが、f2 も一重引用符がエスケープされています。

repr() は何が起こっているかを示します。最初に f1 の場合:

>>> repr(x)
'"This isn\'t a great example, but it works.\\n\\n"'

そしてf2:

>>> repr(y)
'\'This isn\\\'t a great example, but it wasn\\\'t meant to be. \\n"But doesn\\\'t it demonstrate the problem?," she said.\\n\\n\''

この種の行動は私を夢中にさせます。何が起こっているのか、それを一貫させるにはどうすればよいですか? 問題がある場合は、プレーンテキストで読み取り、操作し、最終的には適切にエスケープされた文字が表示されるように (Javascript コードに貼り付けるために) 書き出そうとしています。

4

2 に答える 2

15

Python は文字列リテラルを提供していますが、これを Python に戻すと、同じ文字列になります。これはrepr()、文字列の (「表現」の略) として知られています。これは、最初に指定された文字列と一致しない可能性があります (おそらく実際には一致しません)。これを行うには非常に多くの方法があり、Python は最初にどのように指定されたかについて何も記録しません。

最初の例を二重引用符で囲みますが、単一引用符が含まれていないため、正常に機能します。2 番目の文字列には二重引用符が含まれているため、二重引用符を区切り文字として使用することはできません。代わりに、単一引用符を使用し、バックスラッシュを使用して文字列内の単一引用符をエスケープします (この方法で二重引用符をエスケープする必要はなく、単一引用符よりも多くの二重引用符があります)。これにより、表現が可能な限り短く保たれます。

この振る舞いがあなたを夢中にさせる理由はなく、一貫性を持たせる必要もありません。repr()Python のインタラクティブ モードで値を覗いている場合にのみ、文字列の を取得します。文字列を実際にprint使用するか、別の方法で使用すると、再構成された文字列リテラルではなく、文字列自体が得られます。

JavaScript 文字列リテラルを取得したい場合、最も簡単な方法はjsonモジュールを使用することです:

import json
print json.dumps('I said, "Hello, world!"')
于 2013-09-20T19:12:19.267 に答える
7

との両方f1f2、完全に通常の、エスケープされていない一重引用符が含まれています。

repr見た目が違うという事実は無意味です。

同じ文字列を表すさまざまな方法があります。たとえば、これらはすべて同等のリテラルです。

"abc'def'ghi"
'abc\'def\'ghi'
'''abc'def'ghi'''
r"abc'def'ghi"

文字列のrepr関数は常に、その文字列の有効な表現であるリテラルを生成するだけですが、生成するものに正確に依存するべきではありません。(実際、そもそもデバッグ目的以外で使用することはめったにありません。)


言語は を生成するために使用するアルゴリズムをどこにも定義していないためrepr、各実装のバージョンごとに異なる可能性があります。

それらのほとんどは、一重引用符または二重引用符を使用して、できるだけ多くのエスケープされた内部引用符を回避しようとしますが、それも保証されていません. 特定の実装とバージョンのアルゴリズムを本当に知りたい場合は、ほとんどの場合、ソースを確認する必要があります。たとえば、CPython 3.3 では、 内unicode_reprで、各タイプの引用符の数をカウントします。次に、一重引用符があり、二重引用符がない場合は、"代わりに を使用し'ます。


文字列の「the」表現が必要な場合は、運が悪いです。そのようなものはないからです。しかし、文字列の特定の表現が必要な場合は、問題ありません。必要な形式を知っているだけです。ほとんどの形式、誰かが既にコードを書いており、多くの場合、それは標準ライブラリにあります。C リテラル文字列、JSON でエンコードされた文字列、ASCII RFC822 ヘッダーに収まる文字列を作成できます。しかし、これらの形式はすべて互いに (そして Python リテラルとは) 異なる規則を持っているため、ジョブに適した関数を使用する必要があります。 .

于 2013-09-20T19:12:09.850 に答える