Аргументы командной строки в виде байтов вместо строк в python3 - PullRequest
2 голосов
/ 24 августа 2010

Я пишу программу на python3, которая получает имена файлов для обработки из аргументов командной строки. Я не понимаю, как правильно обрабатывать разные кодировки.

Я думаю, что я предпочел бы рассматривать имена файлов как байты, а не строки, так как это исключает опасность использования неправильной кодировки. Действительно, некоторые из моих имен файлов используют неправильную кодировку (латинская 1, когда моя системная локаль использует utf-8), но это не мешает работе таких инструментов, как ls. Я бы тоже хотел, чтобы мой инструмент был устойчивым к этому.

У меня две проблемы: аргументы командной строки выдаются мне в виде строк (я использую argparse), и я хочу сообщать пользователю об ошибках в виде строк.

Я успешно адаптировал свой код для использования двоичных файлов, и мой инструмент может обрабатывать файлы, имена которых являются недопустимыми в текущей кодировке по умолчанию, при условии, что они повторяются через файловую систему, потому что я преобразовываю аргументы в двоичные файлы рано, и использовать двоичные файлы при вызове функций fs. Когда я получаю аргумент имени файла, который недопустим, он передается мне как строка в кодировке Юникод со странными символами, такими как \udce8. Я не знаю, что это такое, и пытаться закодировать его всегда не удастся, будь то с помощью utf8 или с соответствующей (неправильной) кодировкой (здесь латинский номер 1).

Другая проблема связана с сообщениями об ошибках. Я ожидаю, что пользователи моего инструмента проанализируют мой стандартный вывод (следовательно, хотят сохранить имена файлов), но при сообщении об ошибках на stderr я бы лучше закодировал его в utf-8, заменив недопустимые последовательности соответствующими символами «недопустимый / вопросительный знак».

Итак,

1) Есть ли лучший, совершенно другой способ сделать это? (да, исправление имен файлов запланировано, но я все же хотел бы, чтобы мой инструмент был надежным)

2) Как получить аргументы командной строки в их исходном двоичном виде (предварительно не декодированном для меня), зная, что для неправильных последовательностей перекодирование декодированный аргумент завершится неудачно, и

3) Как мне сказать кодеку utf-8 заменять недопустимые, некодируемые последовательности какой-либо недопустимой меткой, а не умирать на мне?

Ответы [ 2 ]

2 голосов
/ 24 августа 2010

Когда я получаю аргумент имени файла что неверно, однако, это передал мне в виде строки Unicode с странные символы, такие как \ udce8.

Это суррогатные персонажи. Младшие 8 бит - это исходный неверный байт.

См. PEP 383. Не декодируемые байты в системных символьных интерфейсах .

0 голосов
/ 24 августа 2010

Не идите вразрез: имена файлов - это строки, а не байты.

Вы не должны использовать bytes, когда следует использовать string.bytes - это кортеж целых чисел.string - это кортеж символов.Это разные понятия.То, что вы делаете, это как использование целого числа, когда вы должны использовать логическое значение.

(Внизу: Python хранит все строки в памяти под Unicode; все строки хранятся одинаково. Кодировка определяет, как Python преобразуетвстроенные байты в этот формат в памяти.)

Ваша операционная система хранит имена файлов в виде строк в определенной кодировке.Я удивлен, что вы говорите, что некоторые имена файлов имеют разные кодировки;насколько я знаю, кодировка имени файла является общесистемной.Такие функции, как open, используются по умолчанию для кодировки имени файла системы по умолчанию, например.

...