Какой вид имеют окончания файлов перевода
Несмотря на то, что мировая культура в лице Википедии и Пола Маккартни уверяет нас, что Mary had a little lamb, на территории одной восьмой части суши продолжают считать, что на самом деле «У Мэри был ягнёнок». Кто же на самом деле был у Мэри, и как записать это на разных языках мира? Попробуем выяснить это (а также понять, что думают по этому поводу японцы) вместе с нашим любимым Python-ом и встроенным в него модулем поддержки многоязычных переводов gettext.
Приступим
Начнём с того, что напомним, что библиотека gettext используется для перевода не только программ на Python, а на многих различных языках. Он позволяет использовать в нашей программе шаблоны фраз, которые можно переводить с помощью отдельных и независимых файлов перевода. В самой программе мы, как и прежде, выводим текст сразу на экран, на диск, в логи или ещё куда-нибудь, всего лишь пометив переводимые строки особым образом; библиотека gettext же позволяет взять эти переводимые строки, наборы файлов перевода, и, при наличии подходящего для текущего языка файла перевода, подставить нужную строку.
В Python доступ к механизмам библиотеки gettext осуществляется с помощью идущего в комплекте с Python-ом модуля gettext. Так что не будем путать систему gettext как таковую (внешнюю по отношению к Python-у и совершенно не требующуюся ему для работы сущность; тем не менее, в комплект которой входят удобные утилиты для работы с файлами gettext) и встроенный в Python модуль gettext.
name = _("Mary")
animal = _("lamb")
print _("%s had a little %s") % (name, animal)
При использовании модуля gettext принято помечать переводимые строки вызовом функции _() . Пока эта функция не определена (впрочем, никто не мешает нам временно определить что-нибудь наподобие _ = lambda x: x ), поэтому программа даже наверняка не сможет запуститься… но нам пока и не надо.
Вы уже, наверное, подумали, что сейчас мы будем создавать новый текстовый файл с ассоциациями, в котором надо будет не забыть указать все переводимые строки из программы? В нашем случае таких строк всего 3, но в серьёзной программе их может быть намного больше…
Шаблон перевода: .pot
… вы почти угадали. Создавать файл мы будем. Но при этом воспользуемся приятной возможностью системы gettext — анализом файлов с исходниками на предмет переводимых строк. Поскольку мы их благоразумно пометили вызовом функции _() ещё до того, как этот вызов стал всерьёз использовать gettext, теперь синтаксический анализатор может их быстро собрать.
Что это такое? Это шаблон для перевода всей нашей программы. Если у нас есть большая команда переводчиков, то мы можем дать этот шаблон каждому переводчику для каждого целевого языка, и он должен нам будет вернуть заполненный шаблон для его языка. Обычно шаблоны имеют расширение .pot, а заполненные файлы имеют расширение .po.
Синтаксис у файла достаточно прозрачный. Комментарии, пометки авторских прав на перевод, пары из оригинальных строк и переводов. Выкинем из файла всё лишнее, кроме строчки с «Content-Type:» и необходимых для перевода строк, укажем кодировку UTF-8 и напишем переводы:
Файл перевода: .po
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
msgid "Mary"
msgstr "Мэри"
msgid "lamb"
msgstr "ягнёнок"
msgid "%s had a little %s"
msgstr "У %s был маленький %s"
В нашем случае файл достаточно маленький и простой; будь он посложнее, было бы удобнее использовать специализированные редакторы .po-файлов, наподобие Poedit, или «специализированного редактора всего» Emacs.
Скомпилированный файл перевода: .mo
Итак, строки в нашей программе мы перевели. Зря, кстати. gettext направлен исключительно на перевод законченных готовых предложений, и перевод отдельных слов и шаблонов предложений в нём делать опасно… (например, gettext совершенно не поддерживает падежи и рода и кое-как поддерживает разве что различение единственного и множественного числа; так что, чтобы подставить вместо Мэри «Таню» или «Свету», придётся учитывать падеж для каждого возможного употребления исходного имени.) Ну да ладно — в нашем случае это не принципиально. Сейчас у нас задача в другом: подготовить файл перевода к использованию.
Использовать исходный текстовый файл было бы неудобно по соображениям производительности (для программ, в которых много переводимого текста), поэтому система gettext использует скомпилированные в специальный формат файлы. Для компиляции мы можем воспользоваться либо тулой msgfmt из комплекта gettext, либо msgfmt.py из комплекта Python (в дебианоподобных дистрибутивах она входит в состав пакета python2.5-examples). Воспользуемся второй:
Ага, видим файл mary.mo. В отличие от mary.po он уже явно не предназначен для ручного редактирования.
Структура каталогов и запуск программы
Если бы мы подготавливали программу к инсталляции в служебные директории, то мы бы создали примерно такую иерархию (в случае Debian linux): системный каталог /usr/share/locale, в нём подкаталоги для разных языков — ru, en и т.п.; в них — по каталогу LC_MESSAGES, а там уже — файл наподобие mary.mo (с максимально уникальным именем, чтобы не пересечься с другими программами). Но в нашем учебном случае мы просто сделаем подкаталог locale в нашем каталоге, создадим в нём подкаталоги ru/LC_MESSAGES, а в последний уже положим mary.mo.
Теперь наконец добавим в нашу программу поддержку gettext:
gettext.install('mary', './locale', unicode=True)
name = _("Mary")
animal = _("lamb")
print _("%s had a little %s") % (name, animal)
Что изменилось? Мы проимпортировали модуль gettext (ну, это очевидно). А ещё мы проинсталлировали в глобальное пространство программы функцию _(), которая для перевода строк в подкаталоге ./locale (второй аргумент) найдёт каталог с нашей текущей локалью (тот самый подкаталог ru), а в его подкаталоге LC_MESSAGES будет искать юникодный (третий аргумент) файл mary.mo перевода программы mary (первый аргумент).
Что имеется в виду под словом «проинсталлировали»? А то, что, после этого действия, мы можем импортировать другие модули нашей программы, и функция _() в них будет уже определена.
Запускаем нашу программу…
1:/tmp/mary> ./mary.py
У Мэри был маленький ягнёнок
Бонус
Согласно Google Translate, .po-файл для японского языка будет выглядеть примерно так:
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
msgid "Mary"
msgstr "メアリー"
msgid "lamb"
msgstr "子羊"
msgid "%s had a little %s"
msgstr "%sの%sいた"
И для нормальной поддержки японского языка (помимо русского) нам придётся поменять последнюю строку кода на
print (_("%s had a little %s") % (name, animal)).encode('UTF-8')
Проверим в работе:
1:/tmp/mary> LANG=ja_JP.UTF-8 ./mary.py
メアリーの子羊いた
Я пытаюсь использовать что-то в bash, чтобы показать мне окончания строк в файле, напечатанном, а не интерпретированном. Файл представляет собой дамп из служб SSIS / SQL Server, который читается машиной Linux для обработки.
Существуют ли какие - либо переключатели в пределах vi , less , more и т.д.?
Помимо просмотра концов строк, мне нужно знать, к какому типу конца строки это относится ( CRLF или LF ). Как мне это узнать?
Общий совет: если у вас есть представление о том, какую команду * nix / cygwin вы можете использовать, вы всегда можете просмотреть ее справочную страницу для поиска переключателей, которые могут предоставить вам необходимые функции. Например, man less .
Вы можете использовать file утилиту, чтобы указать тип конца строки.
Чтобы конвертировать из "DOS" в Unix:
Чтобы конвертировать из Unix в "DOS":
Преобразование уже преобразованного файла не имеет никакого эффекта, поэтому его можно запускать вслепую (т. Е. Без предварительного тестирования формата), хотя обычные заявления об отказе применяются, как всегда.
@JessChadwick: Да, но только если вы явно устанавливаете tofrodos пакет с sudo apt-get install tofrodos - так же, как вам нужно было бы запустить, sudo apt-get install dos2unix чтобы получить dos2unix и unix2dos .
Команда @DennisWilliamson file до и после команды dos2unix получала одинаковые выходные данные: исходный код xxx.c C, текст ASCII с символами CR, LF. Я обнаружил, что этот файл c имеет ^ M в середине строки, которой нравится xxxxxxx ^ M xxxxxxx
:set list чтобы увидеть окончания строк.
:set nolist чтобы вернуться к нормальной жизни.
Хотя я не думаю, что вы можете видеть \n или \r\n внутри vi , вы можете увидеть, какой тип файла (UNIX, DOS и т. Д.), Чтобы определить, какие окончания строк он имеет .
В качестве альтернативы, bash вы можете использовать od -t c или просто od -c для отображения результатов.
К сожалению, я не думаю, что vi может показать эти конкретные символы. Вы можете попробовать od -c <имя_файла>, которое, я считаю, будет отображать \ n или \ r \ n.имя_файла>
В категории «для чего это стоит» вы можете выполнить grep для CRLF в стиле Dos, введя grep --regex = "^ M", где ^ M - это CTRL + V CTRL + M. Вы можете удалить их, заменив их командой sed. По сути это то же самое, что и dos2unix
В vim: :set fileformat сообщит, какой из unix или dos vim считает, что в конце строки файла. Вы можете изменить его :set fileformat=unix .
Используйте флаг -b при запуске vi / vim, а затем используйте: set list, чтобы увидеть окончания CR (^ M) и LF ($).
@RyanBerger - Похоже, вам не хватает -t. Так и должно быть od -t c file/path , но спасибо за новую программу. Работал отлично!
просто cat -e работает просто отлично.
Здесь отображаются окончания строк Unix ( \n или LF) как $ и окончания строк Windows ( \r\n или CRLF) как ^M$ .
Также работает на OSX. Хорошее решение Просто и сработало у меня, а принятого ответа нет. (Примечание: не было .txt файла)
В оболочке bash попробуйте cat -v . Это должно отобразить возврат каретки для файлов Windows.
(Это работало для меня в rxvt через Cygwin на Windows XP).
Примечание редактора: cat -v визуализирует \r (CR) символы. как ^M . Таким образом, конечные \r\n последовательности будут отображаться как ^M в конце каждой выходной строки. cat -e дополнительно визуализирую \n , а именно как $ . ( cat -et дополнительно визуализирует символы табуляции. как ^I .)
Я хотел посмотреть, есть ли в файле ^ M (Windows / DOS EOL), и только cat -v показал мне это. +1 за это
Исправление: Таким образом, последовательности \ r \ n, заканчивающиеся строкой, будут отображаться как ^ M $
Чтобы показать CR как ^M при меньшем использовании less -u или набрать - u один раз, открыта.
man less говорит:
file обычно будет достаточно. Но для тяжелых случаев попробуйте file -k или dosunix -ih .
Vim - иногда показывает тип файла ( unix vs dos )
Если вы просто хотите посмотреть, какой тип файла у вас есть, вы можете использовать его :set fileformat (это не будет работать, если вы принудительно установите тип файла ). Он вернется unix для файлов Unix и dos для Windows.
Запуск git на машине с Windows XP, используя bash. Я экспортировал свой проект из SVN, а затем клонировал пустой репозиторий.
Затем я вставил экспорт в пустой каталог репозиториев и сделал:
@apphacker, потому что стандартизация окончаний строк менее раздражает, чем необходимость изменять их самостоятельно при разграничении двух файлов. (И, конечно, если вы не согласны, вы можете отключить функцию core.autocrlf).
Я часто касаюсь множества строк, потому что я экспериментирую с разными идеями, добавляю операторы трассировки, чтобы увидеть, как они работают, и т. Д. Тогда я могу захотеть зафиксировать изменение только в двух или трех строках и заставить git полностью игнорировать другие, потому что я положил их обратно, как я их нашел (или я так думал).
@MatrixFrog: ваш редактор, кажется, не работает, не может автоматически определять окончания строк. Что он? Я работаю над гибридными проектами, которые должны иметь несколько файлов LF и некоторые другие файлы CRLF в одном репо. Не проблема для любого современного редактора. Неразбериха с управлением версиями (или передачей файлов) с окончаниями строк, чтобы обойти ограничения редактора, является худшей идеей в истории - очевидно из простой длины объяснений ниже.
Концепция autocrlf заключается в прозрачной обработке преобразования концов строк. И это делает!
Плохая новость : значение необходимо настроить вручную.
Хорошая новость : делать это нужно ОДИН раз за установку git (также возможна настройка каждого проекта).
Как autocrlf работает :
Здесь crlf = маркер конца строки в стиле win, lf = стиль unix (и mac osx).
(pre-osx cr не затронут ни для одного из трех вариантов выше)
Когда появляется это предупреждение (под Windows)
- autocrlf = true если у вас есть Unix-стиль lf в одном из ваших файлов (= RARELY),
- autocrlf = input если у вас есть win-стиль crlf в одном из ваших файлов (= почти ВСЕГДА),
- autocrlf = false - НИКОГДА!
Что означает это предупреждение
Предупреждение « LF будет заменено на CRLF » говорит о том, что вы (имея autocrlf = true ) потеряете свой LF в стиле Unix после цикла фиксации (он будет заменен CRLF в стиле Windows). Git не ожидает, что вы будете использовать LF в стиле Unix под Windows.
Предупреждение « CRLF будет заменен на LF » говорит о том, что вы (имея autocrlf = input ) потеряете свой CRLF в стиле Windows после цикла проверки-подтверждения (он будет заменен на LF в стиле Unix). Не используйте input под окнами.
Еще один способ показать, как autocrlf работает
где x - это CRLF (в стиле Windows) или LF (в стиле Unix), а стрелки обозначают
Значение по умолчанию для core.autocrlf выбирается во время установки git и сохраняется в общесистемной gitconfig ( %ProgramFiles(x86)%\git\etc\gitconfig ). Также есть (каскадирование в следующем порядке):
- «глобальный» (для пользователя) gitconfig, расположенный в ~/.gitconfig , еще один
- «глобальный» (для пользователя) gitconfig в $XDG_CONFIG_HOME/git/config или $HOME/.config/git/config и
- «локальный» (для репо) gitconfig в .git/config в рабочем каталоге .
Итак, напишите git config core.autocrlf в рабочем каталоге, чтобы проверить текущее используемое значение и
Предупреждения
- git config настройки могут быть изменены gitattributes настройками.
- crlf -> lf преобразование происходит только при добавлении новых файлов, crlf файлы, уже существующие в репо, не затрагиваются.
Мораль (для Windows):
- использовать core.autocrlf =, true если вы планируете использовать этот проект также под Unix (и не хотите настраивать ваш редактор / IDE для использования концов строк Unix),
- использовать core.autocrlf =, false если вы планируете использовать этот проект только под Windows ( или вы настроили свой редактор / IDE для использования концов строк Unix),
- никогда не используйте core.autocrlf =, input если у вас нет веских причин ( например, если вы используете утилиты Unix под Windows или если у вас возникают проблемы с makefiles),
PPS Мое личное предпочтение - настройка редактора / IDE для использования окончаний в стиле Unix и настройка core.autocrlf на false .
Ответы на этот вопрос - работа сообщества . Отредактируйте существующие ответы, чтобы улучшить этот пост. В настоящее время он не принимает новые ответы или взаимодействия.
На этот вопрос есть ответы на Stack Overflow на русском : Чтение из файла построчно и запись в массив
Как мне прочитать каждую строку файла в Python и сохранить каждую строку как элемент в списке?
Я хочу прочитать файл построчно и добавить каждую строку в конец списка.
Не используйте file.readlines() в for -loop, сам файл объекта достаточно: lines = [line.rstrip('\n') for line in file]
В случае, если вы работаете с большими данными, использование readlines() не очень эффективно, так как это может привести к MemoryError . В этом случае лучше перебрать файл, используя for line in f: и работая с каждой line переменной.
Я проверил профиль памяти различными способами, приведенными в ответах, используя процедуру, упомянутую здесь . Использование памяти намного лучше, когда каждая строка читается из файла и обрабатывается, как предлагает @DevShark здесь . Удерживать все строки в объекте коллекции не очень хорошая идея, если память ограничена или размер файла велик. Время выполнения одинаково в обоих подходах.
или с удалением символа новой строки:
Лучше всего читать файл по одной строке за раз, а не читать весь файл в память все сразу. Это плохо масштабируется с большими входными файлами. Смотрите ответ ниже Роберт.
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')] Если я пишу таким образом, как я могу закрыть файл после прочтения?
Да, к тому, что здесь делают другие, хотя использование open «менеджера контекста» (или какого-либо другого гарантированного способа его закрытия) не является «лучшей практикой», но на самом деле это не один из тех случаев - когда у объекта больше нет ссылок для него будет сборка мусора и закрытие файла, что должно произойти сразу после ошибки или нет, когда обработка списка завершена.
Это более явно, чем необходимо, но делает то, что вы хотите.
Я предпочитаю этот ответ, поскольку он не требует загрузки всего файла в память (в этом случае он все еще добавляется, array хотя могут быть и другие обстоятельства). Конечно, для больших файлов этот подход может смягчить проблемы.
Присоединение к массиву происходит медленно. Я не могу придумать случай использования, где это лучшее решение.
Это даст «массив» строк из файла.
open возвращает файл, который может быть повторен. Когда вы перебираете файл, вы получаете строки из этого файла. tuple может взять итератор и создать для вас экземпляр кортежа из предоставленного вами итератора. lines это кортеж, созданный из строк файла.
@Vanuan Поскольку после запуска строки не остается никакой ссылки на файл, деструктор должен автоматически закрыть файл.
@NoctisSkytower Я нахожу lines = open(filename).read().splitlines() немного чище и считаю, что он также лучше обрабатывает окончания строк DOS.
@ mklement0 Предполагая, что файл состоит из 1000 строк, a list занимает на 13,22% больше места, чем a tuple . Результаты приходят от from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2) . Создание a tuple занимает примерно на 4,17% больше времени, чем создание list (со стандартным отклонением 0,16%). Результаты приходят от бега from timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2) 30 раз. Мое решение предпочитает пространство над скоростью, когда необходимость в изменчивости неизвестна.
Если вы хотите \n включить:
Если вы не хотите, чтобы \n включены:
В соответствии с Методами Файловых Объектов Питона , самый простой способ преобразовать текстовый файл в list :
Если вам просто нужно перебрать строки текстового файла, вы можете использовать:
Использование with и readlines() :
Если вам не нужно закрывать файл, эта однострочная работа работает:
Вы можете просто сделать следующее, как было предложено:
Обратите внимание, что у этого подхода есть 2 недостатка:
1) Вы храните все строки в памяти. В общем случае это очень плохая идея. Файл может быть очень большим, и вам может не хватить памяти. Даже если он не большой, это просто пустая трата памяти.
2) Это не позволяет обрабатывать каждую строку по мере их чтения. Поэтому, если вы обрабатываете ваши строки после этого, это неэффективно (требуется два прохода, а не один).
Лучший подход для общего случая был бы следующим:
Где вы определяете свою функцию процесса так, как хотите. Например:
(Реализация Superman класса оставлена для вас как упражнение).
Это будет хорошо работать при любом размере файла, и вы пройдете его всего за 1 проход. Как правило, именно так будут работать универсальные парсеры.
Это было именно то, что мне было нужно - и спасибо за объяснение минусов. Будучи новичком в Python, удивительно понять, почему решение - это решение. Ура!
Подумай немного больше Кори. Вы действительно хотите, чтобы ваш компьютер читал каждую строку, ничего не делая с этими строками? Конечно, вы можете понять, что вам всегда нужно обрабатывать их так или иначе.
Вам всегда нужно что-то делать со строками. Это может быть так же просто, как печатать строки или считать их. Нет никакого смысла в том, чтобы ваш процесс читал строки в памяти, но ничего с этим не делал.
Вам всегда нужно что-то делать с ними. Я думаю, что вы пытаетесь подчеркнуть, что вы можете применить функцию ко всем сразу, а не по одному. Это действительно так иногда. Но это очень неэффективно с точки зрения памяти и не позволяет вам читать файлы, если его размер больше, чем у вашего Ram. Вот почему типичные парсеры работают так, как я описал.
@PierreOcinom это правильно. Учитывая, что файл открыт в режиме только для чтения, вы не можете изменить исходный файл с кодом выше. Чтобы открыть файл для чтения и записи, используйте open('file_path', 'r+')
Данные в список
Предположим, что у нас есть текстовый файл с нашими данными, как в следующих строках:
Содержание текстового файла:
- Откройте cmd в том же каталоге (щелкните правой кнопкой мыши и выберите cmd или PowerShell)
- Запустите python и в интерпретаторе напишите:
Скрипт Python:
Используя append:
Или:
Или:
Или:
read().splitlines() предоставляется вам Python: это просто readlines() (что, вероятно, быстрее, так как это менее расточительно).
@EricOLebigot из показанных примеров выглядит read().splitlines() и readlines() не выдает тот же результат. Вы уверены, что они эквивалентны?
Если вы используете только readlines, вам нужно использовать метод strip, чтобы избавиться от \ n в тексте, поэтому я изменил последние примеры, используя понимание списка, чтобы иметь одинаковый вывод в обоих случаях. Итак, если вы используете read (). Readlines (), у вас будет «чистый» элемент со строкой и без символа перевода строки, в противном случае вы должны сделать то, что видите в приведенном выше коде.
Верно. Обратите внимание, что в приведенном выше коде все символы strip() должны быть rstrip("\n") или пробелы вокруг строки удаляются. Кроме того, readlines() в понимании списка нет никакого смысла : лучше просто выполнять итерации по файлу, так как он не тратит время и память, создавая промежуточный список строк.
Чтобы прочитать файл в список, вам нужно сделать три вещи:
- Открыть файл
- Читать файл
- Хранить содержимое в виде списка
К счастью, Python делает это очень легко, поэтому самый короткий способ прочитать файл в список:
Однако я добавлю еще несколько объяснений.
Открытие файла
Я предполагаю, что вы хотите открыть определенный файл, и вы не имеете дело непосредственно с дескриптором файла (или с дескриптором файла). Наиболее часто используемая функция для открытия файла в Python - open это один обязательный аргумент и два необязательных в Python 2.7:
- Имя файла
- Режим
- Буферизация (я проигнорирую этот аргумент в этом ответе)
Имя файла должно быть строкой, которая представляет путь к файлу . Например:
Обратите внимание, что необходимо указать расширение файла. Это особенно важно для пользователей Windows, поскольку такие расширения файлов, как .txt или .doc , и т. Д. По умолчанию скрыты при просмотре в проводнике.
Второй аргумент - mode это r по умолчанию, что означает «только для чтения». Это именно то, что вам нужно в вашем случае.
Но если вы действительно хотите создать файл и / или записать в файл, вам понадобится другой аргумент. Есть отличный ответ, если вы хотите обзор .
Для чтения файла вы можете опустить mode или передать его явно:
Оба откроют файл в режиме только для чтения. Если вы хотите прочитать в двоичном файле в Windows, вам нужно использовать режим rb :
На других платформах 'b' (двоичный режим) просто игнорируется.
Теперь, когда я показал, как с open файлом, давайте поговорим о том факте, что вам всегда это нужно close снова. В противном случае он будет хранить открытый дескриптор файла до тех пор, пока не завершится процесс (или Python не обработает дескриптор файла).
Пока вы можете использовать:
Это не удастся закрыть файл, когда что-то между open и close выдает исключение. Вы можете избежать этого, используя try и finally :
Однако Python предоставляет контекстные менеджеры, которые имеют более симпатичный синтаксис (но open он почти идентичен тому, что try и finally выше):
Последний подход - рекомендуемый подход для открытия файла в Python!
Чтение файла
Хорошо, вы открыли файл, теперь как его прочитать?
open Функция возвращает file объект , и он поддерживает протокол итерации питонов. Каждая итерация даст вам строку:
Это напечатает каждую строку файла. Однако обратите внимание, что каждая строка будет содержать символ новой строки \n в конце (возможно, вы захотите проверить, построен ли ваш Python с поддержкой универсальной новой строки - в противном случае вы могли бы также использовать \r\n в Windows или \r на Mac новые строки). Если вы не хотите, вы можете просто удалить последний символ (или два последних символа в Windows):
Но последняя строка не обязательно имеет завершающий символ новой строки, поэтому не стоит ее использовать. Можно проверить, заканчивается ли он завершающим символом новой строки, и, если это так, удалить его:
Но вы можете просто удалить все пробелы (включая \n символ) в конце строки , это также удалит все другие конечные пробелы, поэтому вы должны быть осторожны, если они важны:
Однако, если строки заканчиваются \r\n (Windows, "новые строки"), .rstrip() это также позаботится о \r !
Vim - иногда показывать переводы Windows
Если вы хотите установить его отдельно для каждого файла, вы можете использовать его :e ++ff=unix при редактировании данного файла.
Резюме
- Используйте with open(. ) as f при открытии файлов, потому что вам не нужно заботиться о закрытии файла самостоятельно, и он закрывает файл, даже если происходит какое-то исключение.
- file объекты поддерживают протокол итерации, поэтому чтение файла построчно так же просто, как и for line in the_file_object: .
- Всегда просматривайте документацию для доступных функций / классов. Большую часть времени идеально подходит для этой задачи или, по крайней мере, один или два хороших. Очевидный выбор в этом случае будет, readlines() но если вы хотите обработать строки перед сохранением их в списке, я бы порекомендовал простое понимание списка.
Последний подход - рекомендуемый подход для открытия файла в Python! Почему это последний, тогда? Разве подавляющее большинство людей не посмотрят на первые несколько строк ответа, прежде чем двигаться дальше?
@AMC Я не особо задумывался над этим, когда писал ответ. Как вы думаете, я должен поставить его в верхней части ответа?
Это может быть лучше, да. Я также только что заметил, что вы упоминаете Python 2, так что это тоже можно обновить.
Ах вопрос был изначально помечен Python-2.x. Возможно, имеет смысл обновить его более широко. Я посмотрю, приду ли я к этому в следующий раз. Спасибо за ваши предложения. Очень признателен!
Чистый и Pythonic способ чтения строк файла в список
Прежде всего, вы должны сосредоточиться на том, чтобы открыть свой файл и прочитать его содержимое эффективным и питонным способом. Вот пример того, как я лично НЕ предпочитаю:
Вместо этого я предпочитаю нижеприведенный метод открытия файлов для чтения и записи, поскольку он очень чистый и не требует дополнительного шага закрытия файла после того, как вы его закончили. В приведенном ниже утверждении мы открываем файл для чтения и присваиваем его переменной infile. Как только код в этом операторе закончится, файл будет автоматически закрыт.
Теперь нам нужно сосредоточиться на переносе этих данных в список Python, потому что они итеративны, эффективны и гибки. В вашем случае желаемая цель состоит в том, чтобы перенести каждую строку текстового файла в отдельный элемент. Для этого мы будем использовать метод splitlines () следующим образом:
Утилитой lupdate извлекаются все строки из исходного текста приложения.
Выполняется перевод строк, с помощью утилиты Qt Linguist .
С помощью утилиты lrelease создается двоичный файл .qm с переводом, который потом может быть загружен приложением.
В качестве примера, рассмотрим процесс перевода приложения Spreadsheet, которое было написано нами в Главе 3. Оно уже содержит все необходимые вызовы tr().
Прежде всего, необходимо внести изменения в файл проекта .pro, чтобы указать -- какие языки будут поддерживаться приложением. Допустим, что мы собираемся включить поддержку немецкого, французского и русского языков, дополнительно к английскому, тогда необходимо в файл spreadsheet.pro добавить раздел TRANSLATIONS:
Здесь мы указали три файла переводов: для немецкого, французского и русского языков. Эти файлы будут созданы при первом запуске утилиты lupdate, а на последующих запусках будут просто дополняться.
Обычно исходные файлы с переводом имеют расширение .ts. Они записываются в формате XML и потому занимают больше места на диске, чем скомпилированные файлы с переводом .qm. Для тех, кому это интересно -- .ts означает "translation source" (исходный текст перевода), а .qm -- "Qt message".
Допустим, что мы уже находимся в каталоге с исходными текстами приложения Spreadsheet. Теперь запускаем lupdate из командной строки:
Ключ -verbose -- необязательный. Он просто заставляет lupdate выводить более подробную информацию в ходе своей работы. Ниже приведен примерный вывод, полученный во время работы утилиты: Каждая строка, которая "завернута" в вызов tr(), заносится в .ts, с пустым местом для перевода. Строки, которые находятся в файле .ui, так же включаются в исходный файл перевода.
По-умолчанию, lupdate предполагает, что все строки, завернутые в вызовы tr(), набраны в кодировке Latin-1. Если это не так, необходимо указать элемент CODEC в файле .pro, например так:
Это необходимо делать в дополнение к вызову QTextCodec::setCodecForTr() в приложении.
Перевод, в файлы spreadsheet_de.ts, spreadsheet_fr.ts и spreadsheet_ru.ts, добавляется переводчиком, с помощью утилиты Qt Linguist .
Чтобы запустить Qt Linguist , в среде Windows, выберите пункт Qt 3.2.x | Qt Linguist в меню Пуск, в среде Unix -- наберите команду linguist. Затем, с помощью меню File|Open, откройте файл с исходным текстом перевода.
С левой стороны главного окна Qt Linguist находится список контекстов переводов. Для Spreadsheet существуют следующие контексты: "FindDialog", "GoToCellDialog", "MainWindow", "SortDialog" и "Spreadsheet". В верхней части с правой стороны находится список строк для текущего контекста. Каждая строка отображается вместе с переводом и флагом Done ("Готово"). В средней области, с правой стороны, вводится текст перевода для текущей строки. И внизу находится список переводов, автоматически предлагаемых утилитой Qt Linguist .
По окончании работы над переводом, файл .ts необходимо преобразовать в файл .qm. Для этого, в приложении Qt Linguist выберите пункт меню File|Release. Обычно, после перевода нескольких строк, выполняются пробные запуски приложения, с созданным файлом .qm, чтобы визуально оценить качество перевода.
Рисунок 15.2. Qt Linguist в действии.
Чтобы перегенерировать все файлы .qm сразу, необходимо запустить утилиту командной строки lrelease: Предположим, что мы сделали перевод на русский язык 19-ти строк, причем установили признак Done для 17-ти из них. В этом случае мы получим от lrelease примерно такой вывод: Непереведенные строки, при пробном запуске приложения, будут отображаться на языке оригинала. Флаг Done никак не используется утилитой lrelease, он предназначен исключительно для переводчика, чтобы напоминать о том, какие строки имеют окончательный перевод, а какие требуют уточнения.
В случае внесения изменений в исходный код приложения, содержимое файлов .ts может "устареть". Чтобы этого не происходило нужно всякий раз запускать утилиту lupdate, добавлять перевод для вновь появляющихся строк и пересобирать файлы .qm. Некоторые команды разработчиков синхронизируют перевод так часто, насколько это только возможно, другие предпочитают дождаться окончательного релиза приложения и только тогда приступают к переводу.
Утилиты lupdate и Qt Linguist достаточно "умны". Переведенные строки, необходимость в которых уже отпала, все равно сохраняются в исходных файлах с переводами, на тот случай, если они могут понадобиться в будущем. При обновлении файлов .ts, утилита lupdate использует интеллектуальный алгоритм объединения, который помогает избежать лишней работы по переводу одинаковых строк в различных контекстах.
Хранить содержимое в виде списка
Теперь, когда вы знаете, как открыть файл и прочитать его, пришло время сохранить содержимое в списке. Самый простой вариант - использовать list функцию:
В случае, если вы хотите убрать завершающие символы новой строки, вы можете использовать вместо этого понимание списка:
Или даже проще: .readlines() метод file объекта по умолчанию возвращает list строку:
Это также будет включать в себя завершающие символы новой строки, если вы не хотите их использовать, я бы порекомендовал [line.rstrip() for line in f] подход, потому что он избегает хранения двух списков, содержащих все строки в памяти.
Есть дополнительная опция для получения желаемого результата, однако она довольно «неоптимальная»: read полный файл в строке, а затем разделенный на новые строки:
Они позаботятся о конце новой строки, потому что split персонаж не включен. Однако они не идеальны, потому что вы сохраняете файл как строку и как список строк в памяти!
Пытаться file -k
Краткая версия: file -k somefile.txt скажу вам.
- Он будет выводиться with CRLF line endings для концов строк DOS / Windows.
- Он выведет with LF line endings для концов строки MAC.
- А для Linux / Unix строка "CR" будет просто выводиться text . (Так что, если он явно не упоминает какой-либо вид, line endings то это неявно означает: «Концы строк CR» .)
Длинную версию смотрите ниже.
Пытаться dos2unix -ih
Я не знал этого, когда писал пример выше, но:
На самом деле получается, что dos2unix выдаст вам строку заголовка, если вы будете использовать -ih (сокращение --info=h ) следующим образом:
И еще один «настоящий» момент: формат заголовка действительно легко запомнить: вот две мнемоники:
- Это DUMB (слева направо: d для Dos, u для Unix, m для Mac, b для спецификации).
- А также: «DUM» это просто алфавитный порядок D, U и M.
Vim - всегда показывать переводы Windows как ^M
Если вы предпочитаете всегда видеть символы новой строки Windows в vim render as ^M , вы можете добавить эту строку в ваш .vimrc :
Это заставит vim интерпретировать каждый файл, который вы открываете, как файл unix. Так как файлы Unix имеют \n символ новой строки, файл Windows с символом новой строки \r\n будет по-прежнему отображаться правильно (благодаря \n ), но будет иметь ^M в конце файла (именно так vim отображает \r символ).
Vim - всегда показывать тип файла ( unix vs dos )
Если вы хотите в нижней строке Vim всегда отображать то , что FILETYPE вы редактируете (и вы не принудительно установить тип файла в UNIX) , вы можете добавить в ваш statusline с
set statusline+=\ % .
Моя полная статусная строка представлена ниже. Просто добавь это к себе .vimrc .
внизу вашего файла
Пример из реальной жизни: кодировка сертификата
Я иногда должен проверить это для файлов сертификата PEM.
Проблема с обычным file заключается в следующем: иногда он пытается быть слишком умным / слишком конкретным.
Давайте попробуем небольшой тест: у меня есть несколько файлов. И один из этих файлов имеет разные окончания строк. Который из?
(Кстати: вот так выглядит один из моих типичных каталогов "работы с сертификатами".)
Давайте попробуем регулярно file :
Да. Это не говорит мне об окончаниях строк. И я уже знал, что это сертификаты. Мне не нужно было «файл», чтобы сказать мне это.
Что еще можно попробовать?
Вы можете попробовать dos2unix с --info переключателем, как это:
Это говорит о том, что: yup, «0.example.end.cer» должен быть нечетным человеком. Но что за концы строк? Как вы знаете , выходной формат dos2unix наизусть? (Я не.)
Но, к счастью, есть опция --keep-going (или -k для краткости) file :
Превосходно! Теперь мы знаем, что наш нечетный файл имеет CRLF окончания строки DOS ( ). (А у других файлов есть LF окончания строк Unix ( ). Это не явно в этом выводе. Это неявно. Это просто способ, которым file ожидается «обычный» текстовый файл.)
(Если вы хотите поделиться моей мнемоникой: «L» для «Linux» и «LF».)
Теперь давайте преобразуем преступника и попробуем еще раз:
Хорошо. Теперь все сертификаты имеют окончания Unix.
дальнейшее чтение
@standalone: интересно. Я читал странные вещи о опции под названием «igncr» - и то, что вы говорите, звучит так. Но не могу воспроизвести то, что вы описываете. (Я попробовал внутри Bash внутри mintty, который поставляется с Git-for-Windows, «git version 2.24.0.windows.1».)
Хм, я попробовал file -k Accounts.java внутри mintty, который поставляется с git-for-windows тоже, но моя версия git version 2.21.0.windows.1
Вы можете использовать, xxd чтобы показать шестнадцатеричный дамп файла, и отыскать символы "0d0a" или "0a".
Вы можете использовать, cat -v как подсказывает @warriorpostman.
У меня работает с cat v 8.23. Концы строк Unix не будут печатать никакой дополнительной информации, но окончания строк DOS будут печатать «^ M».
Это должно быть то, что я сталкиваюсь с 8.21, учитывая тот факт, что я использую окончания строки Unix.
Вы можете использовать команду todos filename для преобразования в окончания DOS и fromdos filename в конец строки UNIX. Чтобы установить пакет в Ubuntu, введите sudo apt-get install tofrodos .
Вы можете использовать vim -b filename для редактирования файла в двоичном режиме, который будет показывать символы ^ M для возврата каретки, а новая строка указывает на наличие LF, указывая окончания строки Windows CRLF. Под LF я имею в виду, \n а под CR я имею в виду \r . Обратите внимание, что при использовании параметра -b файл всегда будет редактироваться в режиме UNIX по умолчанию, как указано [unix] в строке состояния, что означает, что при добавлении новых строк они заканчиваются LF, а не CRLF. Если вы используете обычный vim без -b для файла с окончанием строки CRLF, вы должны увидеть [dos] показанный в строке состояния, и вставленные строки будут иметь CRLF в качестве конца строки. Документация vim для fileformats настройки объясняет сложности.
Кроме того, у меня недостаточно очков, чтобы комментировать ответ Notepad ++, но если вы используете Notepad ++ в Windows, используйте меню View / Show Symbol / Show End of Line для отображения CR и LF. В этом случае отображается LF, тогда как для vim LF указывается новой строкой.
Я вывожу свой вывод в текстовый файл. Затем я открываю его в notepad ++, затем нажимаю кнопку «Показать все символы». Не очень элегантно, но это работает.
Этот вопрос помечен как Linux, и я не думаю, что notepad ++ предназначен для Linux. Это должно работать для окон, хотя.
Читайте также: