You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows CMD与PowerShell中Python标准IO差异及CP1252字符问题问询

问题描述

我有一个两行的Python 3.10.7程序stdin.py:

import sys
print(sys.stdin.read())

还有一个单行文本文件ansi.txt(CP1252编码),内容为:

‘I am well’ he said. 

其中左右引号分别为0x91和0x92。

在Windows 10 CMD模式下,执行python stdin.py < ansi.txt可正常输出原内容;但在PowerShell中执行cat .\ansi.txt | python .\stdin.py时,引号会变为?。此外,Python直接读取该文件、PowerShell单独显示文件内容时,均可正常识别这些CP1252引号字符。

现问询:为何CMD与PowerShell搭配Python时行为不同?Python为何无法识别PowerShell管道传入的CP1252引号字符?

原因分析

1. CMD与PowerShell的管道/重定向编码逻辑差异

  • CMD的重定向(<)操作会直接传递文件的原始字节流给Python的标准输入,不做编码转换。Python在Windows下默认用系统ANSI编码(通常是CP1252,和文件编码匹配)解码输入字节,因此能正确解析引号。
  • PowerShell的cat是Get-Content的别名,它默认会先把CP1252编码的文件解码为Unicode字符串,再通过管道传递。而PowerShell管道的默认输出编码是UTF-16LE(Windows原生Unicode编码),但Python标准输入仍会用系统ANSI编码解码字节流,UTF-16LE字节用CP1252解码会出现无法识别的字符,最终显示为?。

2. 单独操作正常的原因

  • Python直接读取文件时,默认调用系统ANSI编码(CP1252)解码,和文件编码一致,所以能正确解析。
  • PowerShell单独显示文件时,Get-Content用系统ANSI编码解码文件,控制台也用同编码输出,因此能正常显示引号。
解决办法

有三种可行的解决方式:

  • 方式一:指定PowerShell输出编码为CP1252
    执行命令时明确设置Get-Content的输出编码,让传递给Python的字节流和文件编码一致:

    Get-Content .\ansi.txt -Encoding CP1252 | python .\stdin.py
    
  • 方式二:让Python用UTF-16LE解码标准输入
    修改Python脚本,指定和PowerShell管道匹配的编码:

    import sys
    print(sys.stdin.read(encoding='utf-16'))
    
  • 方式三:用CMD的type命令替代cat
    在PowerShell中调用CMD的type命令,它和CMD重定向逻辑一致,直接传递原始字节:

    type .\ansi.txt | python .\stdin.py
    

内容的提问来源于stack exchange,提问作者P. Wormer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:05:25