2016-08-27 2 views
15

Под Powershell v5, Windows 8.1, Python 3. Почему это не удается и как исправить?Как `[System.Console] :: OutputEncoding/InputEncoding` с Python?

[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 
п»ї???? 
+0

Каждая программа имеет свой собственный стандартный ввод/stdout. Глобальных системных параметров нет, которые могут переопределить настройки другой программы, поэтому все, что вы установили в PowerShell, влияет только на PowerShell. Если возможно, установите кодировку stdin python вручную. Я думаю, для этого должно быть много примеров. – wOxxOm

+0

@wOxxOm Есть ли некоторые соглашения для Python? Кажется, он получает свою стандартную кодировку от системной. Но почему не stdin? – Artyom

+0

Я хочу сказать, что каждая программа использует собственную эвристику и логику, поэтому все, что вы установили в PowerShell, не относится к обработке python для stdin. Ну, вообще. Python 3 пытается быть умным и угадывать stdin-кодировку, но вы не можете * полагаться на это, конечно. Как я уже сказал, должно быть много примеров, как установить stdin-кодирование в python. – wOxxOm

ответ

8

Вы трубопроводные данных в Python; в этот моментPython больше не привязан к TTY (вашей консоли) и не догадается, что такое кодировка. Вместо этого используется локаль системы по умолчанию; на вашей системе, которая является cp1251 (кодовая страница на основе Windows Latin-1).

Установите PYTHONIOENCODING environment variable переопределять:

PYTHONIOENCODING
Если установлено перед запуском интерпретатора, она перекрывает кодировку, используемую для стандартного ввода/стандартный вывод/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, и на ненасыщенном или не перенаправляемом трубе.

+0

Благодарим вас за ответ.Тем не менее он печатает тогда: «Активная кодовая страница: 65001 UTF-8 UTF-8 ????" – Artyom

+0

@Artyom: вы могли бы протестировать с помощью 'sys.stdout.write (repr (sys.stdin.readline()))' пожалуйста? Таким образом, мы можем видеть содержимое этой строки, и если это Python или Powershell, все становится путаным. –

+0

Тогда это '\ ufeff ???? \ n'. Powershell получает его правильно напечатанным, если не пишется в Python. Это нарушает мою веру в использование Python под Powershell;) – Artyom

2

Почему бы не вставить CPython в powershell ?! CPython так просто вставлять, и powershell очень хорош REPL до play with .NET and COM objects. Вот простое введение в использование 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

+1

Ценное дополнение! Тем не менее вопрос не ответил (выглядит как ошибка). Интересно, будет ли pythonnet запускать скрипты python, которые правильно работают с кодировкой. Да, 'stdin' там правильно кодируется; так выглядит многообещающе – Artyom

+1

Не могли бы вы опубликовать, если pythonnet получает и работает правильно, как в вопросе? – Artyom

Смежные вопросы