Как `[System.Console]:: OutputEncoding/InputEncoding` с Python?
В Powershell v5, Windows 8.1, Python 3. Почему это не удается и как исправить?
[system.console]::InputEncoding = [System.Text.Encoding]::UTF8;
[system.console]::OutputEncoding = [System.Text.Encoding]::UTF8;
chcp;
"import sys
print(sys.stdout.encoding)
print(sys.stdin.encoding)
sys.stdout.write(sys.stdin.readline())
" |
sc test.py -Encoding utf8;
[char]0x0422+[char]0x0415+[char]0x0421+[char]0x0422+"`n" | py -3 test.py
печатает:
Active code page: 65001
cp65001
cp1251
п»ї????
Ответы
Ответ 1
Вы передаете данные в Python; в этот момент Python stdin
больше не привязан к TTY (вашей консоли) и не догадается, что такое кодировка. Вместо этого используется локаль системы по умолчанию; в вашей системе, что cp1251 (кодовая страница на основе Windows Latin-1).
Установите переменную окружения PYTHONIOENCODING
для переопределения:
PYTHONIOENCODING
Если он установлен перед запуском интерпретатора, он переопределяет кодировку, используемую для stdin/stdout/stderr, в синтаксисе encodingname:errorhandler
. Обе части encodingname
и :errorhandler
являются необязательными и имеют то же значение, что и в str.encode()
.
PowerShell, похоже, не поддерживает переменные окружения командной строки, как это делают оболочки UNIX; проще всего просто установить переменную:
Set-Item Env:PYTHONIOENCODING "UTF-8"
или даже
Set-Item Env:PYTHONIOENCODING "cp65001"
поскольку кодовая страница Windows UTF-8, по-видимому, не совсем UTF-8, в зависимости от версии Windows, а также от перенаправления или переадресации труб.
Ответ 2
Почему бы не вставить CPython в powershell?! CPython так просто вставлять, и powershell очень хорош REPL для играть с объектами .NET и COM. Вот простое введение в pythonnet из PowerShell. Обратите внимание, как кодирование автоматически распространяется с powershell на python.
Windows PowerShell
Copyright (C) 2015 Microsoft Corporation. All rights reserved.
PS C:\Users\denfromufa> [system.console]::InputEncoding = [System.Text.Encoding]::UTF8;
PS C:\Users\denfromufa> [system.console]::OutputEncoding = [System.Text.Encoding]::UTF8;
PS C:\Users\denfromufa> [Reflection.Assembly]::LoadFile("C:\Python\Miniconda3_64b\Lib\site-packages\Python.Runtime.dll")
GAC Version Location
--- ------- --------
False v4.0.30319 C:\Python\Miniconda3_64b\Lib\site-packages\Python.Runtime.dll
PS C:\Users\denfromufa> $gil = [Python.Runtime.Py]::GIL()
PS C:\Users\denfromufa> $sys=[Python.Runtime.Py]::Import("sys")
PS C:\Users\denfromufa> $sys.stdin.encoding.ToString()
cp65001
PS C:\Users\denfromufa> $sys.stdout.encoding.ToString()
cp65001
PS C:\Users\denfromufa> $gil.Dispose()
PS C:\Users\denfromufa> [Python.Runtime.PythonEngine]::Shutdown()
PS C:\Users\denfromufa>
[EDIT]
Вот пакет snek
, выпущенный одним из разработчиков powershell
для встраивания Python
в powershell
:
https://github.com/adamdriscoll/snek