我正在更新一些别人写的Python2代码,这部分:
def exec(self, content, query):
# query = "city_68"
content = content.strip().strip(',').decode('utf-8', 'ignore')
query = query.decode('utf-8', 'ignore')
query_list = query.split('|')
这会在Python3中产生一个错误:
File "/Users/cong/bexec.py", line 708, in bexec
content = content.strip().strip(',').decode('utf-8', 'ignore')
AttributeError: 'str' object has no attribute 'decode'
参数content和query都是字符串。所以我去掉了解码部分:
content = content.strip().strip(',')
# query = query.decode('utf-8', 'ignore')
现在它不再抱怨了。这样做安全吗?我猜在Python3中它不再需要decode()了。
正确。在Python 3中,如果你有一个str
值,你可以假设它是一个正确的Unicode码点序列,而不是一个需要从(比如说)UTF-8解码成Unicode字符串的字节序列。如果你有一个bytes
值,你必须先解码它,以便得到一个合适的Unicode字符串。
在Python 2中,边界更宽松。unicode
值绝对是一个正确的Unicode字符串(并且在Python 3中被重命名为str
),而str
值可能是一个"real"仅限ascii的字符串值或任意二进制数据:您无法仅从类型判断。
因此,str
类型支持encode
和decode
方法,允许在str
类型的两边之间切换。
在Python 3中,使用更严格定义的角色,您可以调用str.encode
来获取bytes
值,也可以调用bytes.decode
来获取str
值。您无法解码str
或进一步编码bytes
。str.decode
和bytes.encode
根本不存在。
在某种意义上,所有文件都是二进制文件:它们由字节流组成。我们所说的文本文件只是一个文件,其字节打算使用特定的文本解码器解码,如ASCII或UTF-8,而不是像JPEG解码器,JVM或您的CPU本身。
当您使用open
以文本模式(默认)打开文件时,它的read
方法返回str
值,这是通过将文件对象的解码器应用于从文件读取的原始字节而产生的。
当您使用open
以二进制模式打开文件时,其read
方法返回bytes
值,原始字节保留未编码,供您根据需要处理。