Python3 writes a gzip file - memoryview: a byte-like object is needed, not 'str'

I want to write a file. Based on the file name, this may or may not be compressed using the gzip module. Here is my code:

 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) 

I open the recording file in binary mode and encode my string for writing. However, I get the following error:

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

Why is my object not a byte? I get the same error if I open the file with 'w' and skip the encoding step. I also get the same error if I remove the '.gz' from the file name.

I am using Python3.5 on Ubuntu 16.04

+8
source share
4 answers

print is a relatively complex function. It writes str to the file, but not the str you pass, it writes str , which is the result of rendering the parameters.

If you already have bytes, you can directly use fd.write(bytes) and take care of adding a new line if you need it.

If you do not have bytes, make sure fd open to receive text.

+4
source

you can convert it to bytes like this.

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

For me, changing the gzip flag to 'wt' did the job. I could write the original line without going around it. (tested on python 3.5, 3.7 on ubuntu 16).

From python 3 gzip doc - quote: "... The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', 'wb', 'x' or 'xb' for binary mode or "rt", "at", "wt" or "xt" for text mode ... "

 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 
+1
source

You can serialize it using pickle .

First serialize the object to be written using pickle , then using gzip .

To save 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) 

To load 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) 
0
source

Source: https://habr.com/ru/post/1012826/


All Articles