【问题标题】:python3 zip reads gzipped text file as bytes string but python2 izip read as normal stringpython3 zip 将 gzipped 文本文件读取为字节字符串,但 python2 izip 读取为普通字符串
【发布时间】:2021-04-09 01:38:28
【问题描述】:

再次,我正在将 python2 代码转换为 python3。当我用 zip 替换 itertools.izip 时遇到了麻烦。这是一个例子:

我有两个压缩的文本文件: 数据1.txt.gz 有内容

a
b

和data2.txt.gz

e
f

python2 izip 版本

from itertools import izip
import sys
import gzip

def read(file):
  fh = gzip.open(file,"rb")
  with fh as f:
    while True:
      l1 = f.readline()
      if not l1:
        break
      l2 = f.readline()
      yield [l1, l2]

for a,b in izip(read("data1.txt.gz"),read("data2.txt.gz")):
  sys.stdout.write("%s\n%s\n" % (a,b))

这显示了

的输出
['a\n', 'b\n']
['e\n', 'f\n']

但是,对于 python3 zip 版本:

import sys
import gzip

def read(file):
  fh = gzip.open(file,"rb")
  with fh as f:
    while True:
      l1 = f.readline()
      if not l1:
        break
      l2 = f.readline()
      yield [l1, l2]

for a,b in zip(read("data1.txt.gz"),read("data2.txt.gz")):
  sys.stdout.write("%s\n%s\n" % (a,b))

输出变成:

[b'a\n', b'b\n']
[b'e\n', b'f\n']

为什么?

这会导致我的程序崩溃 在那之后。为了解决这个问题,我可以添加

a = list(map(bytes.decode,a))
b = list(map(bytes.decode,b))

在 for 语句之后。 据推测,这看起来不太好,可能也会更慢 但是有没有更好看和更快的方法来做到这一点? 提前非常感谢。

【问题讨论】:

  • 如果不以二进制方式打开它会发生什么?而是通过 open('rt') 使用文本模式
  • 如果输入是纯文本。 python3 zip 不会使它们成为字节字符串。那么可能 itertools.izip 默认进行了转换?
  • 尝试以文本模式打开。查看行为的答案。
  • 这只是术语的变化。 Python 2 str 类型与 Python 3 的 bytes 类型完全相同。 Python 2 在让你混合使用 strunicode 方面要宽松得多,所以它可能会应用你甚至不知道的自动转换。

标签: python-3.x gzip


【解决方案1】:

在我使用 python3 的系统上:

>>> import gzip
>>> sample_zip_file = 'x1.txt.gz'
>>> 
>>> fh_textmode = gzip.open(sample_zip_file, 'rt')
>>> fh_binarymode = gzip.open(sample_zip_file, 'rb')
>>> 
>>> data_textmode = fh_textmode.read()
>>> data_binarymode = fh_binarymode.read()
>>> 
>>> type(data_textmode)
<class 'str'>
>>> type(data_binarymode)
<class 'bytes'>
>>> 

【讨论】:

  • 如果我们确定 gzip 压缩的文件是文本文件,则以 rt 方式打开它可能是一种适用于 python2 和 python3 的更简洁的方式。
猜你喜欢
  • 1970-01-01
  • 2017-09-06
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
相关资源
最近更新 更多