最近在做一个项目,同时使用Go语言和Python3,需要用Python3执行一个Go程序,然后获取Go程序的输出。于是我自然而然想到了Python3的标准库subprocess,这个库顾名思义,就是用来在一个进程中执行其他进程然后获取执行状况与输出的。
查看文档,发现subprocess库提供了一个叫做getoutput的函数,正好满足需求:
于是就很开心地使用这个函数,然后测试,发现报错。经过一番纠结之后,终于发现是编码问题,然后通过修改源码中一个变量解决了这个问题。下面用一个例子来复现问题与解决方案吧~
首先我们新建两个程序源码,Hello.go 和 sayHello.py.
Hello.go的代码如下:
编译运行,可以看到,这个程序的输出是“你好呀,Luca!”这个字符串:
之后编写sayHello.py,执行Hello.exe然后获取并打印输出。代码如下:
看起来一切都没问题,执行程序吧~~~BOOM!!:
发现程序报编码错误,gbk的字库不能解码汉字。嗯,对于Pythoner们来说,这是个常见问题啦。只要设置一下getoutput函数的编码方式就好了……嗯?这个函数只接受一个参数?不能设置encoding?
既然有这个尴尬问题,那就只能从源码入手了。subprocess库的源码是Python3的目录下的Lib文件夹里的subprocess.py。经过一番查找,终于定位了encoding的初始化位置,在Popen类的__init__函数中,第643行:
可以看到在这里encoding的值设置为None,看来就是系统的默认字库了。查了一下,发现我的Windows10家庭中文版系统的默认字库是gbk:
这个貌似不是很好改,那就试试把encoding改为utf8吧:
保存,然后再次运行sayHello.py,Bingo,问题解决啦!:
总结:通过修改subprocess.py的第643行的encoding变量,就可以设置Python脚本对其他程序输出的编码解码方式。而这个函数之所以不提供显式的编码设置方式,可能还是因为没想到这个库会这么奇怪地被使用吧哈哈哈。所以,如果某个需要被Python脚本执行的程序输出是日文韩文阿拉伯文的话,只要把encoding修改成对应的字库,应该就没有问题啦!
十有九人堪白眼
百无一用是书生
联系客服