在我的代码中,我使用utf-8编码了一个字符串。我得到输出,将其转换为字符串,然后将其发送到其他程序。另一个程序获取此字符串,但是,当我尝试对该字符串进行解码时,它给我一个错误,AttributeError:'str'对象没有属性'decode'。我需要将编码后的数据作为字符串发送,因为我的其他程序在json中接收到它。我的第一个程序在python 3中,另一个程序在python 2中。
# my first program
x = u"宇宙"
x = str(x.encode('utf-8'))
# my other program
text = x.decode('utf-8')
print(text)
我应该怎么做才能将第二个程序接收的字符串转换为字节,以便解码工作?
答案 0 :(得分:1)
正确回答此问题的最重要部分是有关如何将这些对象传递给Python2程序的信息:您正在使用JSON。
所以,和我在一起:
在程序1中执行.encode
步骤之后,便有了一个bytes对象。通过在其上调用str(...)
,您只是在该字节对象上放了一个转义层,然后将其转回一个字符串-但是当此字符串按原样写入文件或通过网络传输时,它将再次进行编码-所有非ASCII令牌通常都使用\u
前缀和每个字符的代码点进行转义-但原始的中文字符本身现在已以utf-8编码并进行了双转义。
Python的JSON加载方法已经将json数据的内容解码为文本字符串:因此完全不需要解码方法。
简而言之:要传递数据,只需在第一个程序中将原始文本编码为JSON,并且在目标Python 2程序的json.load
之后不要进行任何解码:
# my first program
x = "宇宙"
# No str-encode-decode dance needed here.
...
data = json.dumps({"example_key": x, ...})
# code to transmit json string by network or file as it is...
# my other program
text = json.loads(data)["example_key"]
# text is a Unicode text string ready to be used!
在执行操作时,您可能会得到双倍编码的文本-我将在Python 3控制台上对其进行模仿。我将打印每个步骤的结果,以便您不了解正在发生的转换。
In [1]: import json
In [2]: x = "宇宙"
In [3]: print(x.encode("utf-8"))
b'\xe5\xae\x87\xe5\xae\x99'
In [4]: text = str(x.encode("utf-8"))
In [5]: print(text)
b'\xe5\xae\x87\xe5\xae\x99'
In [6]: json_data = json.dumps(text)
In [7]: print(json_data)
"b'\\xe5\\xae\\x87\\xe5\\xae\\x99'"
# as you can see, it is doubly escaped, and it is mostly useless in this form
In [8]: recovered_from_json = json.loads(json_data)
In [9]: print(recovered_from_json)
b'\xe5\xae\x87\xe5\xae\x99'
In [10]: print(repr(recovered_from_json))
"b'\\xe5\\xae\\x87\\xe5\\xae\\x99'"
In [11]: # and if you have data like this in files/databases you need to recover:
In [12]: import ast
In [13]: recovered_text = ast.literal_eval(recovered_from_json).decode("utf-8")
In [14]: print(recovered_text)
宇宙
答案 1 :(得分:-1)
主要是您要处理两个不同的python版本,并且存在库问题。
documentation库解决了这个问题。
Six提供了用于包装Python 2和Python 3之间差异的简单实用程序。它旨在支持无需修改即可在Python 2和3上运行的代码库。
使用该库并以这种方式解码。
import six
def bytes_to_str(s, encoding='utf-8'):
"""Returns a str if a bytes object is given."""
if six.PY2 and isinstance(s, bytes):
return s.decode(encoding)
return s
text = bytes_to_str(x)
print(text)