open(' filepath',' rb')和open(rb' filepath')之间的区别是什么?它们之间存在一些编码差异

时间:2017-09-28 01:10:42

标签: python file

open('filepath', 'rb')open(rb'filepath')之间的区别是什么?当我尝试散列内容时,第二个给出了以下与Unicode相关的错误:

  

TypeError:必须在散列之前对Unicode对象进行编码

这是我的示例代码

import hashlib
f1 = open('findMaxConsecutiveOnes.py', 'rb')
f2 = open(rb'findMaxConsecutiveOnes.py')

hashlib.sha512()
hasher.update(f1)
hasher.update(f2) #error comes up here

我使用的是Python 3.6.0

1 个答案:

答案 0 :(得分:2)

open('findMaxConsecutiveOnes.py', 'rb')将使用二进制I / O(findMaxConsecutiveOnes.py)打开文件r以获取读取模式(b)。

rb'findMaxConsecutiveOnes.py'中,r前缀将字符串文字标记为raw(在此特定情况下不执行任何操作),而b前缀将其标记为{ {3}},表示生成的对象是bytes对象,不是 str对象。

open()并不关心这一点;它只会将第一个操作数转换为字符串。但是,由于省略了 second 参数(文件打开模式),因此使用默认模式打开文件,该模式为'r'(不是'rb')因此打开用于文本模式下的读访问。

所以这三个表达式实际上是等价的:

  • open(rb'findMaxConsecutiveOnes.py')
  • open('findMaxConsecutiveOnes.py')
  • open('findMaxConsecutiveOnes.py', 'r')

以文本模式打开的文件将从读取操作返回Unicode str对象,而以二进制模式打开的文件将返回bytes个对象。 hashlib hasher函数只能散列字节;他们不了解或关心Unicode字符串。这是有道理的,因为哈希函数本身仅对字节进行操作。这是错误的来源。

以二进制模式打开文件(您给出的第一个示例)通过不尝试解码字符来避免此问题。它只读取原始字节,hashlib很高兴。 (它也不会浪费任何能量来解码字符,否则它将不得不在以后重新编码。)