subprocess.Popen 在 PyCharm 中的反应方式与在 Windows CMD 中的反应方式不同,当有像 �这样的“有趣”字符时
Posted
技术标签:
【中文标题】subprocess.Popen 在 PyCharm 中的反应方式与在 Windows CMD 中的反应方式不同,当有像 �这样的“有趣”字符时【英文标题】:subprocess.Popen doesn't react the same way in PyCharm as in Windows CMD when there is "funny" character like � 【发布时间】:2020-08-07 20:07:26 【问题描述】:首先,是的,我已经搜索过了,但没有找到任何解决方案。所以,问题是:
我在 PyCharm 中创建了第一个 python 脚本CommandLine.py
,它从网站请求一个 Json 文件,然后我在终端上打印结果。
for val in my_json[:200]:
i += 1
print(" - ".format(str(i).zfill(2), val))
这个命令行脚本是这样使用的:
python CommandLine.py --user MyUserName --password MyPWD --website www.about.com --output C:\Users\MyName\MyFolder --mail YesOrNo and so on...
一切正常,我得到了结果,即使是俄文字符、日文字符以及结果中的“有趣”字符(比如这个:�)。它在 PyCharm 和 Windows CMD 中的工作方式相同(像这样的“有趣”字符 - 都打印在两者中)。
但是第一个脚本对所有参数都有些烦人(对我来说,对朋友来说......),所以我创建了第二个名为 GUI.py
的 Python 脚本。它是带有Tkinter
python 库的图形用户界面。您可以使用其上的所有 Entry 小部件来选择所需的参数。然后单击 Button 小部件并在名为“Console”的 Text 小部件中获得结果(以“模拟”终端)。我用subprocess.Popen
这样做:
cmd = 'python CommandLine.py --user MyUserName --password MyPWD
--website www.about.com --output C:\Users\MyName\MyFolder
--mail YesOrNo and so on...'
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')
while True:
returnStatus = process.poll()
output = process.stdout.readline()
if returnStatus is not None:
break
if output:
line = output.strip() # leave the white space
console.insert('end', line + '\n')
console.yview_moveto(1)
console.update()
GUI.py
在 PyCharm 中运行良好,我得到与 CommandLine.py
相同的结果(带有非拉丁字符),没有代码错误。
但是!对,但是。在 Windows CMD 中,第二个脚本 GUI.py
总是因以下代码错误而崩溃:
Traceback (most recent call last):
File "C:\Users\MyName\MyFolder\CommandLine.py", line 343, in <module>
print(" - ".format(str(i).zfill(2), val))
File "C:\Python37\lib\encodings\cp1252.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 10-11: character maps to <undefined>
我不明白为什么,因为第一个脚本 CommandLine.py
单独在 PyCharm 和 Win CMD 中都可以正常工作。
subprocess.Popen
是 CMD 的问题吗?我想是的,但找不到解决方案。
我试过了:
在process = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')
中使用mbcs
、ansi
、ISO-8859-1
更改编码
删除process = subprocess.Popen(cmd, stdout=subprocess.PIPE, encoding='utf-8')
中的编码
添加Shell=True
在python GUI.py
之前在CMD中执行chcp 65001
没有解决问题,仍然有代码错误。
顺便说一句,我使用subprocess.Popen
来获取“实时”输出以将其打印为我的“控制台”小部件。
我哪里错了?请需要帮助。 提前致谢。
PS:对不起,英语不是我的母语。
【问题讨论】:
encodings\cp1252
确实会成为所有其他字符的问题,而不是非常有限的 Windows Latin-1 编码,通常你的 chcp 65001
会解决这个问题。但事实仍然是,您有趣的�
仍将映射到一个未定义的字符——而且这无法根据设计显示。你有那个字符的 Unicode 值吗?如果始终是同一个,请在尝试打印之前将其过滤掉。
问题是第一个脚本单独在 PyCharm 和 CMD 中运行良好。那么为什么它在第二个脚本中不起作用。这可能是我未来修改第一个脚本以转义这些字符的解决方法。但如果它有效(第一个脚本)为什么要改变它?只是暂时想更改第二个脚本...
【参考方案1】:
也许尝试使用env='PYTHONIOENCODING': 'utf-8'
调用 subproces.Popen?
根据您的错误,Python 选择了 cp1252 的“系统编码”(用于 IO 流),除了与您告诉子进程期望的编码不兼容之外,不能代表所有可能的字符你从你的输入中得到。
PYTHONIOENCODING
应该覆盖 Python 用来选择系统编码的过程,并将输出流编码为 utf-8,它应该能够表示任何输入,并且符合预期你的包装器。
【讨论】:
致命的 Python 错误:_Py_HashRandomization_Init:无法获取随机数来初始化 Python以上是关于subprocess.Popen 在 PyCharm 中的反应方式与在 Windows CMD 中的反应方式不同,当有像 �这样的“有趣”字符时的主要内容,如果未能解决你的问题,请参考以下文章
python subprocess.popen stdin.write
subprocess.wait() 不等待 Popen 进程完成(使用线程时)?
subprocess.Popen("echo $HOME"... 和 subprocess.Popen(["echo", "$HOME"]