Каков список настроек Python, которые влияют на кодирование, декодирование и печать? - PullRequest
0 голосов
/ 11 февраля 2019

Когда я сталкиваюсь с проблемами печати Unicode, я хочу знать, что я должен проверить.В моем конкретном случае я использую установленный модуль, который печатает символы в кодировке Юникод с использованием неправильного кодека.

Есть несколько разных мест, которые влияют на кодирование и декодирование Python при различных обстоятельствах.И, в частности, как python обрабатывает печатаемые данные в различных обстоятельствах.

Некоторые вещи не в порядке:

  • общие переменные среды LC_ALL, LANG
  • Python sys настройка модуля sys.getdefaultencoding()

Что еще я забыл?

Меня интересует только Python 3.

1 Ответ

0 голосов
/ 11 февраля 2019

вещей для проверки

Вот что я нашел, в порядке того, как я рекомендую их проверять:

  • переменные среды LC_ALL, LANG, LC_CTYPE,LANGUAGE
  • Переменные среды, специфичные для Python PYTHONIOENCODING, PYTHONCOERCECLOCALE(на влияние которой может влиять программный аргумент -E; можно проверить sys.flags.ignore_environment)
    • Консольная кодировка Windows-специфическая PYTHONLEGACYWINDOWSSTDIO
  • Python sys module
    • function sys.getdefaultencoding() (функция следствия sys.setdefaultencoding удалена из Python 3)
    • sys.stdin.encoding
    • sys.stdout.encoding
    • sys.stderr.encoding
    • настройка кодировки файловой системы sys.getfilesystemencoding()
  • Заголовок файла Python -*- coding: utf-8 -*-
  • locale модуль
    • функциявызов locale.nl_langinfo(locale.CODESET) (не работает на Windows Python 3.7, работает на Debian Python 3.5)
    • функция locale.getdefaultlocale
    • функция locale.getpreferredencoding (работает по-разному в некоторых системах)
  • gettext модуль и его различные средства (я не буду перечислять их все)
    • содержимое каталогов, передаваемых некоторым функциям, таким как gettext.install(application, directory) или gettext.bindtextdomain(domain, directory)

печать значений

Вот быстрый скрипт для перечисления значений большинства из них:

import os, sys, locale

print('environment:')
print('-E (ignore PYTHON* environment variables) ? %s' %
      (True if sys.flags.ignore_environment else False))
for env in ('LC_ALL', 'LANG', 'LC_CTYPE',
            'LANGUAGE', 'PYTHONIOENCODING',
            'PYTHONLEGACYWINDOWSSTDIO'):
    if env in os.environ:
        print('"%s"="%s"' % (env, os.environ[env]))
    else:
        print('"%s" not set' % env)

print()
print('sys module:')
print('getdefaultencoding "%s"' % sys.getdefaultencoding())
print('sys.stdin.encoding "%s"' % sys.stdin.encoding)
print('sys.stdout.encoding "%s"' % sys.stdout.encoding)
print('sys.stderr.encoding "%s"' % sys.stderr.encoding)

print()
print('locale:')
try:
    getattr(locale,'nl_langinfo')
    print('locale.nl_langinfo(locale.CODESET) "%s"' \
          % locale.nl_langinfo(locale.CODESET))
except AttributeError:
    print('locale.nl_langinfo not available')
print('locale.getdefaultlocale()[1] "%s"' \
      % locale.getdefaultlocale()[1])
print('locale.getpreferredencoding() "%s"' \
      % locale.getpreferredencoding())

напечатанные значения на трех системах

  • Windows 10 с 3,7
  • Debian 9 с 3,5
  • Ubuntu 14 с 3,4

В Windows 10 с использованием Python 3.7 это печатает

environment:
-E (ignore PYTHON* environment variables) ? False
"LC_ALL" not set
"LANG" not set
"LC_CTYPE" not set
"LANGUAGE" not set
"PYTHONIOENCODING"="UTF-8"
"PYTHONLEGACYWINDOWSSTDIO" not set

sys module:
getdefaultencoding "utf-8"
sys.stdin.encoding "UTF-8"
sys.stdout.encoding "UTF-8"
sys.stderr.encoding "UTF-8"

locale:
locale.nl_langinfo not available
locale.getdefaultlocale()[1] "cp1252"
locale.ngetpreferredencoding() "cp1252"

В Debian 9 с использованием Python 3.5 это печатает

environment:
-E (ignore PYTHON* environment variables) ? False
"LC_ALL" not set
"LANG"="en_GB.UTF-8"
"LC_CTYPE" not set
"LANGUAGE" not set
"PYTHONIOENCODING" not set
"PYTHONLEGACYWINDOWSSTDIO" not set

sys module:
getdefaultencoding "utf-8"
sys.stdin.encoding "UTF-8"
sys.stdout.encoding "UTF-8"
sys.stderr.encoding "UTF-8"

locale:
locale.nl_langinfo(locale.CODESET) "UTF-8"
locale.getdefaultlocale()[1] "UTF-8"
locale.ngetpreferredencoding() "UTF-8"

В Ubuntu 14.04 с использованием Python 3.4 этоотпечатки

environment:
-E (ignore PYTHON* environment variables) ? False
"LC_ALL" not set                                                                                                        
"LANG"="en_US.UTF-8"                                                                                                    
"LC_CTYPE" not set                                                                                                      
"LANGUAGE"="en_US:"                                                                                                     
"PYTHONIOENCODING" not set                                                                                              
"PYTHONLEGACYWINDOWSSTDIO" not set                                                                                      

sys module:                                                                                                             
getdefaultencoding "utf-8"                                                                                              
sys.stdin.encoding "UTF-8"                                                                                              
sys.stdout.encoding "UTF-8"                                                                                             
sys.stderr.encoding "UTF-8"                                                                                             

locale:                                                                                                                 
locale.nl_langinfo(locale.CODESET) "UTF-8"                                                                              
locale.getdefaultlocale()[1] "UTF-8"                                                                                    
locale.getpreferredencoding() "UTF-8"   

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

Но этот небольшой кусочек может помочь кому-то начать.

Также см. Полезные ответы на SO Вопрос Как установить кодировку sys.stdout в Python3? .

Соответствующие PEP для обзора

Некоторая помощь от этой статьи pymotw , Python с практическими рекомендациями по Unicode , Python sys модуль , Python Locale Module .

...