Входные данные для вашего скрипта Python, по-видимому, представляют собой текст в кодировке UTF-8.
Если вы закодируете свою тестовую строку «übervölkerung» с помощью UTF-8, то первый байт будет C3
, который находится в трассировке в начале вашего сообщения.
Это означает, что вам нужно читать STDIN с текстовым потоком, который декодирует UTF-8, а не ASCII.
У вас уже есть строка, которая создает оболочку вокруг sys.stdin
:
sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', buffering=1)
Это заменяет средство чтения текстового потока по умолчанию (экземпляр io.TextIOWrapper
) новым.
Но вы не указываете входную кодировку, поэтому используется кодировка по умолчанию, которая определяется средой (на основе переменных среды, специфичных для ОС).
В вашем случае кодировка, по-видимому, по умолчанию ASCII, а это не то, что вам нужно.
Вам нужен UTF-8, поэтому напишите:
sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', encoding='UTF-8')
(Конечно, вы можете оставить параметр buffering=1
там, если считаете, что он вам нужен.)
Кроме того, os.fdopen
- это просто более ограниченная версия встроенной функции open
. Так что вы можете просто использовать его, ничего не теряя:
sys.stdin = open(sys.stdin.fileno(), 'r', encoding='UTF-8')
Кстати, разница в количестве символов, которую вы видите между Ruby и Python, связана с тем, что вы смотрите на разные вещи.
В коде Ruby вы смотрите на байты текста в кодировке UTF-8, а в Python вы смотрите на кодовые точки (Unicode).
Во втором случае каждое число соответствует одному символу, а несколько чисел соответствуют символу в первом случае.
Чтобы увидеть значения байтов в Python, выполните:
>>> a = "übervölkerung"
>>> list(a.encode('utf8'))
[195, 188, 98, 101, 114, 118, 195, 182, 108, 107, 101, 114, 117, 110, 103]
Я не знаю, как увидеть кодовые точки в Ruby.