在使用subprocess调用Windows命令时,遇到了字符串不显示中文的问题,源码以下:#-*-coding:utf-8-*-__author__ = '$USER'python
#-*-coding:utf-8-*- __author__ = '$USER' import subprocess p = subprocess.Popen('nslookup www.qq.com', stdout=subprocess.PIPE) p.wait() print('returncode:%d' % p.returncode) out = p.communicate() for i in out: if i is not None: s = str(i, encoding='utf-8') print(s)
输出以下:服务器
returncode:0 File "F:/TECH/python/LearnPython100Days/subprocessSample.py", line 11, in <module> s = str(i, encoding='utf-8') UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb7 in position 0: invalid start byte
结果显示,输出变量在编码为UT-8时出错。这是由于Windows命令行使用的是GBK编码格式(可在命令行属性中查看),而不是UTF-8,所以直接进行转换是不行的。所以,将代码修改成:编码
s = str(i, encoding='GBK')
便可获得正确输出:命令行
returncode:0 服务器: UnKnown Address: 211.137.130.3 名称: https.qq.com Addresses: 2402:4e00:8030:1::7d 121.51.142.21 Aliases: www.qq.com
在项目中,为了不出现乱码,最好将全部的输出所有统一为UTF-8格式。那么,如何实现呢?code
1.使GBK将字节串编码为中文;blog
2.使用UTF-8将中文字符串编码为字节串;utf-8
3.使用UTF-8将该字节串解码为字符串,即获得一串中文。字符串
相关代码以下:源码
for i in out: if i is not None: print('原始字节串(%s):\n%s' %(chardet.detect(i)['encoding'],i)) s = str(i, encoding='GBK') print('中文字符串:\n%s' %s) utf8_bytes = s.encode('UTF-8', 'ignore') print('转码后的字节串(%s):\n%s' % (chardet.detect(utf8_bytes)['encoding'], utf8_bytes)) utf8_str = utf8_bytes.decode('UTF-8') print('转码后的中文字符串:\n%s' %utf8_str)
输出以下:it
returncode:0 原始字节串(ISO-8859-9): b'\xb7\xfe\xce\xf1\xc6\xf7: UnKnown\r\nAddress: 211.137.130.3\r\n\r\n\xc3\xfb\xb3\xc6: https.qq.com\r\nAddresses: 2402:4e00:8030:1::7d\r\n\t 121.51.142.21\r\nAliases: www.qq.com\r\n\r\n' 中文字符串: 服务器: UnKnown Address: 211.137.130.3 名称: https.qq.com Addresses: 2402:4e00:8030:1::7d 121.51.142.21 Aliases: www.qq.com 转码后的字节串(utf-8): b'\xe6\x9c\x8d\xe5\x8a\xa1\xe5\x99\xa8: UnKnown\r\nAddress: 211.137.130.3\r\n\r\n\xe5\x90\x8d\xe7\xa7\xb0: https.qq.com\r\nAddresses: 2402:4e00:8030:1::7d\r\n\t 121.51.142.21\r\nAliases: www.qq.com\r\n\r\n' 转码后的中文字符串: 服务器: UnKnown Address: 211.137.130.3 名称: https.qq.com Addresses: 2402:4e00:8030:1::7d 121.51.142.21 Aliases: www.qq.com
注意:
1.字节串转为GBK,再使用UTF-8转为字节串后,其值发生了变化;
2.使用chardet模块可以检测字节串的编码类型,可是它的结果不保证准确,仅供参考。它将第一个字节串检测成了‘ISO-8859-9’
3.在phthon3中,字符串的encode()方法可以获得字节串,没有decode方法;相应地,字节串bytes.decode()方法将其解码为字符串,没有encode方法。这里与python2不同。