【问题标题】:opening another python 3 process from subprocess.Popen is setting locale default encoding to ANSI_X3.4-1968 but only in certain instances从 subprocess.Popen 打开另一个 python 3 进程正在将语言环境默认编码设置为 ANSI_X3.4-1968 但仅在某些情况下
【发布时间】:2019-02-23 20:42:06
【问题描述】:

这让我发疯了。我有一个主要的 python 3 (3.5.2) 驱动程序/程序,我使用子进程和 popen 来生成我使用 rpyc 与之通信的其他 python 3 进程。这一直运行良好,尤其是在 python 2 中。

我已成功转换为 python 3,并且已验证如果从终端运行,所有这些进程都会成功生成。

要从我的驱动程序启动它们,看起来像这样。

cmd_one = "/path/to/.virtualenv/venv_one/bin/python file_a.py"
cmd_two = "/path/to/.virtualenv/venv_two/bin/python file_b.py"
s_one = subprocess.Popen(cmd_one.split(), stdout=logfile, stderr=logfile)
s_two = subprocess.Popen(cmd_two.split(), stdtou=logfile, stderr=logfile)

这在 Python 2.7 中效果很好。

但是,当我升级到 Python 3 时,我发现默认编码有些奇怪,我无法理解。对于 cmd_one,效果很好——如果我做一个

import locale
print(locale.getpreferredencoding()) 

它返回UTF-8,就像我期望的那样。但是,对于 cmd_two,我似乎无缘无故地得到了ANSI_X3.4-1968,结果它抛出了大量的 unicodedecode 错误。就像我说的,当在终端中生成时,cmd_one 和 cmd_two 都可以很好地工作并使用正确的默认编码。

我进行了广泛的搜索,但这似乎是一个特例。我不想强制使用默认编码,因为我觉得这掩盖了其他一些问题。 file_b.py 及其组成部分中是否有某些东西以某种方式将编码设置为 ANSII,但它没有看到它在终端中运行? file_b.py 是一个大型 Tensorflow 项目的一部分,它使用了大约 8 个文件,但我查看了所有文件,但找不到任何东西。

这是在ubuntu 16.04 上,默认的python 3 是3.5.2,据我所知,没有办法通过Popen 传递encoding='utf-8'

对到底发生了什么有什么建议吗?

谢谢。

【问题讨论】:

  • 你可以在打开logfile时传递编码...
  • 将 popen 更改为 Popen(抱歉 @Jean-FrançoisFabre)
  • 好,现在查看我的第二条评论 :)
  • 问题是 python 环境的默认编码 - 它不会在写入日志文件时引发错误。我正在做大量机器学习 NLP 字符串/文本的东西,我需要默认编码为 utf-8(这是 python3 的默认值),否则它会破坏一切。当我将它作为子进程打开时,某处正在将其更改为 ascii,并且仅在这种情况下,我无法弄清楚在哪里。
  • 我不是编码专家。对您的问题投赞成票并祝您好运

标签: python python-3.x encoding utf-8 subprocess


【解决方案1】:

在这里,我想我找到了一个解决方案,但我仍然不知道为什么我只需要为这个特定实例执行此操作 - 希望有人可以权衡一下,以便我能更好地理解这一点。

发件人:

https://webkul.com/blog/setup-locale-python3/

当我跑步时:

locale

在我的终端中,作为子进程,我得到:

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

为我修复默认编码的方法是将语言环境环境 LANGUAGE 设置为 en_US.en 并将 LC_ALL 设置为 en_US.UTF-8 变量,然后使用 Popen 将它们直接传递给子进程。

s = subprocess.Popen(cmd_two.split(), env={'LANGUAGE':'en_US.en', 'LC_ALL':'en_US.UTF-8'})

现在它在我的子进程中正确地将默认编码识别为UTF-8,并且一切正常。

谁能给我解释一下?我不需要对我的其他子流程执行此操作,它工作得很好。

【讨论】:

    猜你喜欢
    • 2018-07-22
    • 2016-09-07
    • 2020-04-05
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    相关资源
    最近更新 更多