2013-10-02 56 views
0

我正在用特殊字符(å,ä,ö)寫入JSON數據並將其讀回。然後我在一個子進程命令中使用這些數據。當使用讀取數據時,我無法將特殊字符分別轉換回å,ä和ö。用Python編寫和閱讀JSON,如何解碼/編碼特殊字符?

當運行下面的python腳本,列表中的 「命令」 打印爲:

['cmd.exe', '-Name=M\xc3\xb6tley', '-Bike=H\xc3\xa4rley', '-Chef=B\xc3\xb6rk'] 

但我希望它是打印:

['cmd.exe', '-Name=Mötley', '-Bike=Härley', '-Chef=Börk'] 

的Python腳本:

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

import os, json, codecs, subprocess, sys 


def loadJson(filename): 
    with open(filename, 'r') as input: 
     data = json.load(input) 
    print 'Read json from: ' + filename 
    return data 

def writeJson(filename, data): 
    with open(filename, 'w') as output: 
     json.dump(data, output, sort_keys=True, indent=4, separators=(',', ': ')) 
    print 'Wrote json to: ' + filename 



# Write JSON file 
filename = os.path.join(os.path.dirname(__file__) , 'test.json') 
data = { "Name" : "Mötley", "Bike" : "Härley", "Chef" : "Börk" } 
writeJson(filename, data) 


# Load JSON data 
loadedData = loadJson(filename) 


# Build command 
command = [ 'cmd.exe' ] 

# Append arguments to command 
arguments = [] 
arguments.append('-Name=' + loadedData['Name']) 
arguments.append('-Bike=' + loadedData['Bike']) 
arguments.append('-Chef=' + loadedData['Chef']) 
for arg in arguments: 
    command.append(arg.encode('utf-8')) 

# Print command (my problem; these do not contain the special characters) 
print command 

# Execute command 
p = subprocess.Popen(command , stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

# Read stdout and print each new line 
sys.stdout.flush() 
for line in iter(p.stdout.readline, b''): 
    sys.stdout.flush() 
    print(">>> " + line.rstrip()) 
+0

打印列表,而不是列表中的字符串和特殊字符會奇蹟般地重新出現 – hop

+1

'M \ xc3 \ xb6tley' _is_'Mötley',用utf8編碼,就像你寫的一樣。你的代碼很好。 – georg

+0

@hop - 像這樣打印列表只是爲了說明這些值不包含首字符。它在子進程中.Popen在那裏我得到了真正的問題,因爲參數不包含前面的字符。 – fredrik

回答

3

這是Python中字符串常量的標準表示形式,用於消除編碼i ssues。實際上,這是字符串上的repr()返回的內容。列表的str()函數實現在打印時調用,它的成員會調用repr()來表示它們。

輸出帶有非ASCII字符的字符串的唯一方法就是print它或以其他方式將其寫入流中。有關如何在打印時完成字符轉換,請參見Why does Python print unicode characters when the default encoding is ASCII?。另請注意,對於非ASCII 8位字符,對於爲不同代碼頁設置的終端,輸出會有所不同。

關於解決方案:

最簡單的一個將是使替代str(list)的實施,將調用str()而不是repr() - 注意上面的警告。

def list_nativechars(l): 
    assert isinstance(l,list) 
    return "[" + ", ".join('"'+str(i)+'"' for i in l) + "]" 

現在(在cp866控制檯編碼):

>>> l=["йцукен"] 
>>> print list_nativechars(l) 
["йцукен"] 

在國外的編碼數據:

# encoding: cp858 
<...> 
l= ['cmd.exe', '-Name=Mötley', '-Bike=Härley', '-Chef=Börk'] 
print list_nativechars(l) 

c:\>python t.py 
["cmd.exe", "-Name=MФtley", "-Bike=HДrley", "-Chef=BФrk"]