我怎样才能解决这个问题,而又不浪费太多的代码?
开始时小巧而优雅?
很遗憾,为了防止解码/编码错误,还需要几个额外的步骤。 python 2.x 有很多地方可以进行 implicit 编码/解码,即在你背后未经你的许可。当 python 进行隐式编码/解码时,它使用 ascii 编解码器,如果存在 utf-8(或任何其他非 ascii)字符,这将导致编码/解码错误。因此,您必须找到所有 python 进行隐式编码/解码的地方,并将它们替换为显式编码/解码——如果您希望您的程序在这些地方处理非 ascii 字符。
至少,任何来自外部源的输入都应该在继续之前解码为 unicode 字符串,这意味着您必须知道输入的编码。但是如果将 unicode 字符串与常规字符串结合使用,则会出现编码/解码错误,例如:
#-*- coding: utf-8 -*- #Allows utf-8 characters in your source code
unicode_str = '€'.decode('utf-8')
my_str = '{0}{1}'.format('This is the Euro sign: ', unicode_str)
--output:--
Traceback (most recent call last):
File "1.py", line 3, in <module>
my_str = '{0}{1}'.format('hello', unicode_str)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
因此,您的所有字符串可能都应该解码为 unicode 字符串。那么当你想输出字符串时,你需要对unicode字符串进行编码。
import sys
import json
import codecs
import urllib
def printDict(d, path, filename):
for key, val in d.items(): #key is a unicode string, val is a unicode string or dict
if isinstance(val, dict):
printDict(
val,
u'{0}{1}/'.format(path, key), #format() specifiers require 0,1 for python 2.6
filename
)
else:
key_str = key.encode('utf-8')
val_str = val.encode('utf-8')
url = '{0}{1}{2} -d "{3}"'.format(
filename,
path,
key_str,
val_str
)
print url
url_escaped = urllib.quote(url)
print url_escaped
curl_cmd = 'curl -X PUT'
base_url = 'http://localhost:8500/v1/kv/'
print "{0} {1}{2}".format(curl_cmd, base_url, url_escaped)
filename = sys.argv[1].decode('utf-8')
file_encoding = 'utf-8'
fh = codecs.open(filename, encoding=file_encoding)
my_json = json.load(fh)
fh.close()
print my_json
path = "/"
printDict(my_json, path.decode('utf-8'), filename) #Can the path have non-ascii characters in it?
--output:--
{u'FacetConfig': {u'facet:price-lf-p': {u'prefixParts': u'\xa3'}}}
data.txt/FacetConfig/facet:price-lf-p/prefixParts -d "£"
data.txt/FacetConfig/facet%3Aprice-lf-p/prefixParts%20-d%20%22%C2%A3%22
curl -X PUT http://localhost:8500/v1/kv/data.txt/FacetConfig/facet%3Aprice-lf-p/prefixParts%20-d%20%22%C2%A3%22