Странное исчезновение CR в строках, исходящих из копии содержимого файла, переданной raw_input () - PullRequest
0 голосов
/ 21 февраля 2011

Пытаясь выяснить причины ошибки, я наконец столкнулся со странным поведением функции raw_input () в Python 2.7:

удаляет CR символов пар CR LF только из строк, которые являются результатом ручного копирования (через буфер обмена) содержимого файла. Строки, переданные в raw_input () , которые являются копиями отображения идентичных строк, чем предыдущие, не теряют свои символы CR . Одни CR символы остаются нетронутыми во всех случаях. A CR (возврат каретки) - это \ r символ.

Чтобы быть более понятным, чем с запутанным описанием, вот код, описывающий, что необходимо сделать, чтобы соблюсти факт, чьи приказы нужно только выполнить.

Точка находится в объекте Text : в нем 7 символов вместо 8, которые были переданы raw_input () для создания Text .

Чтобы убедиться, что аргумент, переданный в 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)

Моя ОС - Windows. Интересно, наблюдается ли то же самое в других операционных системах?

Ответы [ 2 ]

2 голосов
/ 21 февраля 2011

sys.stdin открывается в текстовом режиме (вы можете проверить это, отобразив sys.stdin.mode и увидев, что это 'r'). Если вы откроете какой-либо файл в текстовом режиме в Python, то окончание собственной строки платформы (\r\n для Windows) будет преобразовано в простой перевод строки (\n) в строке Python.

Вы можете увидеть это в действии, открыв файл PASTED.txt, используя режим 'r' вместо 'rb'.

0 голосов
/ 22 февраля 2011

После моего поста я мог оторвать взгляд от своего кода, и я действительно заметил, что изменение данных, скопированных из файла и переданных в 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 это в PASTED.txt без перехода в строку Python. Таким образом, когда данные передаются из файла в другой файл, проходя только через буфер обмена, они не изменяются. Этот факт доказывает, что содержимое PRIM.txt не повреждено в буфере обмена, куда копируются данные.

Во-вторых, данные, передаваемые из файла в строку Python через буфер обмена, и raw_input () модифицируется; следовательно, изменение происходит между буфером обмена и строкой 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

Возможно, объяснение модификации \ r \ n Python связано с этими форматами, существующими в буфере обмена, а может и нет. Но я недостаточно разбираюсь во всем этом беспорядке, и я далеко не уверен.

Кто-нибудь может объяснить все вышеперечисленные наблюдения?

.

.

Спасибо за ваш ответ, ncoghlan. Но я не думаю, что это причина:

  • sys.stdin не имеет атрибута mode

  • sys.stdin относится к клавиатуре, насколько я понимаю. Тем не менее, в моем коде данные поступают не от набора текста на клавиатуре, а от вставки через буфер обмена. Это другое.

Ключевым моментом является то, что я не понимаю, как интерпретатор Python может отличать данные, поступающие из буфера обмена, скопированные из файла, и данные, поступающие из буфера обмена, скопированные с экрана

...