【问题标题】:Python3 write gzip file - memoryview: a bytes-like object is required, not 'str'Python3编写gzip文件-memoryview:需要一个类似字节的对象,而不是'str'
【发布时间】:2016-12-02 00:31:15
【问题描述】:

我想写一个文件。根据文件的名称,这可能会或可能不会使用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)

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

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

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

我在 Ubuntu 16.04 上使用 Python3.5

【问题讨论】:

  • print(str('blah blah blah'.encode()), file=fd)。 python 正在尝试编写字节对象的字符串表示形式。
  • @nic 您可以使用 'wt' 标志并直接写入字符串 - 请参阅下面的答案

标签: python gzip typeerror python-3.5


【解决方案1】:

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

来自python 3 gzip doc - 引用:“... mode 参数可以是 '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

【讨论】:

  • 我认为这个答案已经是一个更好的答案(即使看选票)。我们是否应该将此响应更改为“已接受”的答案?
【解决方案2】:

你可以像这样把它转换成字节。

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

【讨论】:

    【解决方案3】:

    print 是一个比较复杂的函数。它将str 写入文件而不是您传递的str,它写入str,这是渲染参数的结果。

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

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

    【讨论】:

    • 使用'fd.write(b"blah blah blah")'
    • @citizenSNIPS,我不明白你的评论。
    • 在 str 前面添加一个 'b' 表示它是一个字节。我相信你想传递一个字节文字。 [](python.org/dev/peps/pep-3112)
    • 我没有。我只提到类型,没有示例数据。
    • 我明白了。我的意思是,如果文件是使用wb 打开的,那么str 需要是byte,然后添加b infront 就可以了。
    【解决方案4】:

    您可以使用pickle 对其进行序列化。

    首先使用pickle序列化要写入的object,然后使用gzip

    保存object

    import gzip, pickle
    filename = 'non-serialize_object.zip'
    # serialize the object    
    serialized_obj = pickle.dumps(object)
    # writing zip file
    with gzip.open(filename, 'wb') as f:
       f.write(serialized_obj)
    

    加载object

    import gzip, pickle
    filename = 'non-serialize_object.zip'
    
    with gzip.open(filename, 'rb') as f:    
       serialized_obj = f.read()
    # de-serialize the object
    object = pickle.loads(serialized_obj)
    

    【讨论】:

      猜你喜欢
      • 2017-08-18
      • 1970-01-01
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      相关资源
      最近更新 更多