Python3写gzip文件 - memoryview:需要一个类似字节的对象,而不是'str'

nic*_*nic 12 python gzip typeerror python-3.5

我想写一个文件.根据文件的名称,这可能会也可能不会被gzip模块压缩.这是我的代码:

import gzip
filename = 'output.gz'
opener = gzip.open if filename.endswith('.gz') else open
with opener(filename, 'wb') as fd:
    print('blah blah blah'.encode(), file=fd)
Run Code Online (Sandbox Code Playgroud)

我正在以二进制模式打开可写文件并编码我要编写的字符串.但是我收到以下错误:

File "/usr/lib/python3.5/gzip.py", line 258, in write
  data = memoryview(data)
TypeError: memoryview: a bytes-like object is required, not 'str'
Run Code Online (Sandbox Code Playgroud)

为什么我的对象不是字节?如果我打开文件'w'并跳过编码步骤,我会得到相同的错误.如果我'.gz'从文件名中删除,我也会得到同样的错误.

我在Ubuntu 16.04上使用Python3.5

mor*_*ork 15

对我来说,将 gzip 标志更改为'wt'就可以了。我可以编写原始字符串,而无需“字节”它。(在 ubuntu 16 上的 python 3.5、3.7 上测试)。

来自python 3 gzip doc - 引用:“...模式参数可以是'r','rb','a','ab','w','wb','x'或'xb'中的任何一个对于二进制模式,或 'rt'、'at'、'wt' 或 'xt' 用于文本模式......”

import gzip

filename = 'output.gz'
opener = gzip.open if filename.endswith('.gz') else open
with opener(filename, 'wt') as fd:
    print('blah blah blah', file=fd)

!zcat output.gz
> blah blah blah
Run Code Online (Sandbox Code Playgroud)

  • 我认为这个答案已经是一个更好的答案(即使看投票)。我们是否应该将此响应更改为“已接受”答案? (3认同)

Nag*_*ama 8

你可以把它转换成这样的字节.

import gzip 
with gzip.open(filename, 'wb') as fd:
   fd.write('blah blah blah'.encode('utf-8'))
Run Code Online (Sandbox Code Playgroud)


Jav*_*ier 5

print是一个相对复杂的功能。它写入str文件,但不str写入您传递的文件,而是写入str呈现参数的结果。

如果已经有字节,则可以fd.write(bytes)直接使用,并在需要时注意添加换行符。

如果没有字节,请确保fd已打开以接收文本。

  • 在str前面添加一个“ b”以表示它是一个字节。我相信您想传递一个字节字面量。[](https://www.python.org/dev/peps/pep-3112/) (2认同)
  • 我懂了。我的意思是,如果文件是使用wb打开的,则str应该是一个字节,并在前面添加b可以做到这一点。 (2认同)