注:以下是Python 3+ 解决方案,但是有一个caveat:
-
随着first下面的解决方案还有第二个 - 但是only ifUTF-8 数据必须发送到 PowerShellstdin流 - 由于中的一个错误powershell.exe
, the Windows PowerShell CLI, the 当前控制台窗口切换到光栅字体(可能具有不同的字体大小),这确实not支持大多数非扩展 ASCII 范围的 Unicode 字符。虽然视觉上很刺耳,这只是一个display(渲染)问题;数据处理正确;切换回支持 Unicode 的字体,例如Consolas
显示正确的输出。
-
相比之下,pwsh.exe
, the PowerShell(核心)(v6+) CLI does not表现出这个问题.
选项 A:配置both控制台and使用PythonUTF-8字符编码before执行你的脚本:
现在,您的原始代码应该按原样工作(显示错误除外)。
Note:
- A 通过一次性配置步骤实现更简单的替代方案是将您的系统配置为使用UTF-8全系统,在这种情况下,OEM 和 ANSI 代码页都设置为
65001
。然而,这已经影响深远 - see 这个答案.
选项 B:(暂时)切换到 UTF-8 进行 PowerShell 调用:
import sys, ctypes, subprocess
# Switch Python's own encoding to UTF-8, if necessary
# This is the in-script equivalent of setting environment var.
# PYTHONUTF8 to 1 *before* calling the script.
sys.stdin.reconfigure(encoding='utf-8'); sys.stdout.reconfigure(encoding='utf-8'); sys.stderr.reconfigure(encoding='utf-8')
# Save the current console output code page and switch to 65001 (UTF-8)
previousCp = windll.kernel32.GetConsoleOutputCP()
windll.kernel32.SetConsoleOutputCP(65001)
# PowerShell now emits UTF-8-encoded output; decode it as such.
command = "powershell.exe ls ~/Desktop"
print(subprocess.run(command, stdout=subprocess.PIPE).stdout.decode())
# Restore the previous output console code page.
windll.kernel32.SetConsoleOutputCP(previousCp)
Note:
- 由于仅设置output控制台页面,避免了 Windows PowerShell 显示错误.
- 如果你也想将输入发送到 PowerShellstdin stream,你必须set the input控制台页面也是如此, via
windll.kernel32.SetConsoleCP(65001)
(which 然后会再次出现显示错误).
[1] This isn't strictly necessary just for correctly decoding PowerShell's output, but matters if you want to pass that output on from Python: Python 3.x defaults to the active ANSI(!) code page for encoding non-console output, which means that Hebrew characters, for instance, cannot be represented in non-console output (e.g., when redirecting to a file), and cause the script to break.