-3

バグと思われる原因を解明しようとして、最終的に Python 2.7 のraw_input()関数の奇妙な動作に遭遇しました。

ファイルの内容を (クリップボード経由で) 手動でコピーした結果の文字列のみから、CR LFのペアのCR文字を削除します。raw_input()に渡された文字列は、以前のものと同じ文字列の表示のコピーであり、CR文字が失われません。単独のCR文字は、すべての場合で変更されません。CR (キャリッジ リターン) は\r文字です。

混乱した説明よりも明確にするために、注文を実行するだけでよいという事実を観察するために何をしなければならないかを説明するコードを次に示します。

ポイントはTextオブジェクトにあります。 Textを作成するためにraw_input()に渡された 8 文字ではなく、7 文字です。

raw_input()に渡された引数が実際に 8 文字であることを確認するために、同じ引数で別のファイルPASTED.txtを作成しました。Notepad ++ウィンドウでのコピーが私に示したように、この問題で何かを確認するのは確かに厄介な作業です:あらゆる種類の行末(\r、\n、\r\n)は端にCR LFとして表示されますそのようなウィンドウ内の行の。

ファイルのデータ全体を選択するには、Ctrl-A をお勧めします。

コーディングや理解の間違いを犯したのか、それとも Python の本当の機能なのか、当惑しています。

あなたからの解説と光を願っています。

with open('PRIM.txt','wb') as f:
    f.write('A\rB\nC\r\nD')
print "  1) A file with name 'PRIM.txt' has just been created with content A\\rB\\nC\\r\\nD"
raw_input("  Open this file and copy manually its CONTENT in the clipboard.\n"+\
          "    --when done, press Enter to continue-- ")


print "\n  2) Paste this CONTENT in a Notepad++ window "+\
      "     and see the symbols at the extremities of the lines."
raw_input("    --when done, press Enter to continue-- ")


Text = raw_input("\n  3) Paste this CONTENT here and press a key : ")
print ("     An object Text has just been created with this pasted value of CONTENT.")


with open('PASTED.txt','wb') as f:
    f.write('')
print "\n  4) An empty file 'PASTED.txt' has just been created."
print "     Paste manually in this file the PRIM's CONTENT and shut this file."
raw_input("     --when done, press Enter to continue-- ")


print "\n  5) Enter the copy of this display of A\\rB\\nC\\r\\nD : \nA\rB\nC\r\nD"
DSP = raw_input('please, enter it on the following line :\n')
print "    An object DSP has just been created with this pasted value of this copied display"


print '\n----------'
with open('PRIM.txt','rb') as fv:
    verif = fv.read()
print "The read content of the file 'PRIM.txt' obtained by open() and read() : "+repr(verif)
print "len of the read content of the file 'PRIM.txt'  ==",len(verif)


print '\n----------'
print "The file PASTED.txt received by pasting the manually copied CONTENT of PRIM.txt"
with open('PASTED.txt','rb') as f:
    cpd = f.read()
    print "The read content of the file 'PASTED.txt' obtained by open() and read() "+\
          "is now : "+repr(cpd)
    print "its len is==",len(cpd)


print '\n----------'
print 'The object Text received through raw_input() the manually copied CONTENT of PRIM.txt'
print "value of Text=="+repr(Text)+\
      "\nText.split('\\r\\n')==",Text.split('\r\n')
print 'len of Text==',len(Text)


print '\n----------'
print "The object DSP received  through raw_input() the copy of the display of A\\rB\\nC\\r\\nD" 
print "value of DSP==",repr(DSP)
print 'len of DSP==',len(DSP)

私のOSはWindowsです。他のオペレーティングシステムでも同じことが観察されるのだろうか。

4

2 に答える 2

2

sys.stdinがテキスト モードで開かれます (これは、 を表示sys.stdin.modeして確認することで確認できます'r')。Python でテキスト モードでファイルを開くと、プラットフォーム ネイティブの行末 ( Windows の場合)は、Python 文字列\r\nの単純な改行 ( ) に変換されます。\n

の代わりにPASTED.txtモードを使用してファイルを開くと、これが動作していることを確認できます。'r''rb'

于 2011-02-21T03:25:55.893 に答える
0

投稿後、コードから検索できました。ファイルからコピーされてraw_input()に渡されるデータの変更は、Pythonがファイル内のデータを直接読み取るときに実行する改行の変更と同じであることに実際に気付きました。 、これはここで証明されています:

with open("TestWindows.txt", 'wb') as f:
    f.write("PACIFIC \r  ARCTIC \n  ATLANTIC \r\n  ")

print "\n- Following string have been written in TestWindows.txt in mode 'wb' :\n"+\
      "PACIFIC \\r  ARCTIC \\n  ATLANTIC \\r\\n  "


print "\n- data got by reading the file TestWindows.txt in 'rb' mode :"
with open("TestWindows.txt", 'rb') as f:
    print "    repr(data)==",repr(f.read())

print "\n- data got by reading the file TestWindows.txt in 'r' mode :"
with open("TestWindows.txt", 'r') as f:
    print "    repr(data)==",repr(f.read())

print "\n- data got by reading the file TestWindows.txt in 'rU' mode :"
with open("TestWindows.txt", 'rU') as f:
    print "    repr(data)==",repr(f.read())

結果:

- Following string have been written in TestWindows.txt in mode 'wb' :
PACIFIC \r  ARCTIC \n  ATLANTIC \r\n  

- data got by reading the file TestWindows.txt in 'rb' mode :
    repr(data)== 'PACIFIC \r  ARCTIC \n  ATLANTIC \r\n  '

- data got by reading the file TestWindows.txt in 'r' mode :
    repr(data)== 'PACIFIC \r  ARCTIC \n  ATLANTIC \n  '

- data got by reading the file TestWindows.txt in 'rU' mode :
    repr(data)== 'PACIFIC \n  ARCTIC \n  ATLANTIC \n  '

まず、ファイルPASTED.txtには、ファイルPRIM.txtと同じコンテンツが含まれています。これは、 PRIM.txtのコンテンツをコピーし、Python文字列で転送せずにPASTED.txtに貼り付けた結果です。したがって、データがファイルからクリップボードのみを通過する別のファイルに移動する場合、データは変更されません。この事実は、PRIM.txtのコンテンツが、コピーによってデータが配置されたクリップボードに破損していないことを証明しています。

次に、クリップボードとraw_input()を介してファイルからPython文字列に移動するデータが変更されます。したがって、変更はクリップボードとPython文字列の間で行われます。そのため、 raw_input()は、ファイルの読み取りからデータを受信するときのPythonインタープリターと同じように、クリップボードから受信したデータの解釈を行う可能性があると思いました。

次に、 \ r \n\nに置き換えるのは、「Windowsの性質」のデータが「Pythonの性質」のデータになり、クリップボードに変更が加えられないためであるという考えを刺繍しました。これは、Windowsオペレーティングシステムの制御下にある部分であるためです。

残念ながら、画面からコピーされてraw_input()に渡されたデータが改行の変換を受けないという事実\ r \ nは、このデータがWindowsのクリップボードを通過するという事実にもかかわらず、私の小さな概念を破ります。

次に、Pythonはデータのソースではなく、データに含まれる情報のためにデータの性質を知っていると思いました。そのような情報は「フォーマット」です。Windowsのクリップボードに関する次のページを見つけました。実際、クリップボードによって記録される情報にはいくつかの形式があります。

http://msdn.microsoft.com/en-us/library/ms648709(v=vs.85).aspx

たぶん、Pythonによる\ r \ nの変更の説明は、クリップボードに存在するこれらの形式にリンクされているかもしれませんし、そうでないかもしれません。しかし、私はこのすべての混乱を十分に理解しておらず、確信が持てません。

誰かが上記のすべての観察を説明することができますか?

答えてくれてありがとう、ncoghlan。しかし、それが理由ではないと思います。

  • sys.stdinには属性モードがありません

  • sys.stdinは、私が理解している限り、キーボードを指します。ただし、私のコードでは、データはキーボードでの入力ではなく、クリップボードを介した貼り付けから取得されます。違います。

重要な点は、Pythonインターペッターが、ファイルからコピーされたクリップボードからのデータと、画面からコピーされたクリップボードからのデータをどのように区別できるかを理解していないことです。

于 2011-02-22T16:04:16.723 に答える