歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Python中使用subprocess.Popen返回值亂碼解決方案

問題描述

在python 2.7中,使用subprocess.Popen()調用*nix命令,並通過管道,獲取其輸出,並將其返回值格式化成utf-8格式,但是對於返回值出現中文時,會造成轉碼錯誤,具體情況如下:

# -*- coding: utf-8 -*-

import subprocess

MY_RPM_FILE_PATH = '/home/dongliang.ma/rpmbuild/RPMS/noarch/q-yumtools-server-1.1.0-1.el6.noarch.rpm'

try:
    cmd_args        = ['rpm', '-qip', MY_RPM_FILE_PATH]
    infos          = subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=False).stdout.readlines()
    unicode_text    = u''.join(infos)
    print unicode_text
except Exception, _ex:
    print 'ERROR: %s' % str(_ex)

問題分析

從python的報錯來看,是中文編碼超出了ASCII碼的表示范圍,具體報錯的代碼為:

unicode_text    = u''.join(infos)

既然是無法表示,我的第一反應就是進行轉碼,於是將代碼改寫:

# -*- coding: utf-8 -*-

import subprocess

MY_RPM_FILE_PATH = '/home/dongliang.ma/rpmbuild/RPMS/noarch/q-yumtools-server-1.1.0-1.el6.noarch.rpm'

try:
    cmd_args        = ['rpm', '-qip', MY_RPM_FILE_PATH]
    infos          = subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=False).stdout.readlines()
    unicode_text    = u''
    for line in infos:
        unicode_text = unicode_text + line.encode('utf-8')
    print unicode_text
except Exception, _ex:
    print 'ERROR: %s' % str(_ex)

但是經過轉換後,代碼運行報錯和先前一樣,經過分析,在執行下面代碼時,問題就已經發生:

infos          = subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=False).stdout.readlines()

那麼現在問題就定位到如何讓infos這個變量能夠存儲中文,經過查閱文檔,發現python有一個defaultencoding的概念,即默認使用的編碼,只要將這個屬性設置為utf-8,那麼就可以正確存儲中文,其具體設置方法是使用:

reload(sys)
sys.setdefaultencoding('utf-8')

經過上述設置後,即可正確處理中文信息。

最終方案

# -*- coding: utf-8 -*-

import sys
import subprocess

MY_RPM_FILE_PATH = '/home/dongliang.ma/rpmbuild/RPMS/noarch/q-yumtools-server-1.1.0-1.el6.noarch.rpm'

try:
    reload(sys)
    sys.setdefaultencoding('utf-8')
    cmd_args        = ['rpm', '-qip', MY_RPM_FILE_PATH]
    infos          = subprocess.Popen(cmd_args, stdout=subprocess.PIPE, shell=False).stdout.readlines()
    unicode_text    = u''.join(infos)
    print unicode_text
except Exception, _ex:
    print 'ERROR: %s' % str(_ex)

運行結果:

總結

python默認使用的編碼是ASCII,這會導致國際化的問題,一個比較好的做法是,在程序運行時,將默認編碼修改為utf-8;

在python源文件中使用unicode字符時,一定要將python文件保存為utf-8格式,而不是僅僅在開頭加上# -*- coding: utf-8 -*-這個bug,導致我調試發送郵件時浪費了不少時間。

Copyright © Linux教程網 All Rights Reserved