LP3THW ex17:PowerShell中Python复制文本文件乱码问题排查
《笨办法学Python3》示例17乱码问题解答
背景
学习《笨办法学Python3》示例17时,严格按照书中代码编写程序并在PowerShell运行。通过命令 echo "This is a test file." > test.txt 创建test.txt,经Python代码复制到test1.txt后,文件末尾出现乱码“ഀ”,且文件大小为46字节(书中预期为21字节),当前使用Python3.9.13。
问题1:这是Python还是PowerShell的问题?
是PowerShell与Python文件读写编码不匹配共同导致的问题,核心触发点在PowerShell的默认输出编码设置上。
问题2:如何修改代码解决该问题?
提供两种可行方案:
- 方案一:修改Python代码,指定文件编码
原书中的基础代码(示例):
修改后代码(指定编码):from sys import argv script, from_file, to_file = argv in_file = open(from_file) indata = in_file.read() out_file = open(to_file, 'w') out_file.write(indata) in_file.close() out_file.close()from sys import argv script, from_file, to_file = argv # 以UTF-16LE编码读取PowerShell创建的文件,以UTF-8编码写入新文件 with open(from_file, 'r', encoding='utf-16le') as in_file: indata = in_file.read() with open(to_file, 'w', encoding='utf-8') as out_file: out_file.write(indata) - 方案二:修改PowerShell创建文件的命令
换用Set-Content命令直接创建UTF-8编码的文件,之后使用原书中的Python代码即可正常复制:Set-Content -Path test.txt -Value "This is a test file." -Encoding UTF8
问题3:该修复方案的原理是什么?
- 方案一原理:PowerShell的
echo(Write-Output的别名)重定向输出默认使用UTF-16LE编码(双字节编码),而Python3默认以UTF-8编码读取文件。指定encoding='utf-16le'读取文件,能正确解析PowerShell生成的双字节编码内容;写入时指定UTF-8编码,可生成与书中一致的单字节编码文件,解决乱码和大小异常问题。 - 方案二原理:直接以UTF-8编码创建源文件,与Python默认读取编码匹配,读取和写入过程中不会出现编码解析错误,复制后的文件内容、大小均与预期一致。
问题4:问题的根源是什么?
根源在于PowerShell与Python的默认文件编码不匹配:
- PowerShell在Windows环境下,
echo >重定向输出的默认编码为UTF-16LE(Windows系统核心组件多采用UTF-16编码),导致创建的test.txt为双字节编码,包含额外的编码标记字节。 - Python3默认以UTF-8编码读取文件,将UTF-16LE的双字节内容错误解析为UTF-8字符,从而产生乱码;同时双字节编码使得文件大小翻倍(加上编码标记字节),出现46字节的异常大小。
内容的提问来源于stack exchange,提问作者Dorian
相关产品推荐
相关产品推荐

