如何使用 gzip 压缩字符串并在 python 2.7 中编码

How to compress the string using gzip and encode in python 2.7

我试图在 python 2.7 中使用 gGIP 压缩和编码我的字符串,我可以在 Python 3 中做到这一点,但我在 [= 中没有得到相同的输出32=]2.7版本代码:

Python 3:

import sys
import redis
import io import StringIO
import gzip

redisConn = redis.StrictRedis(host="127.0.0.1", port=6379, db=0)

myValue = "This is test data"
result = gzip.compress(myValue.encode())
redisConn.set("myKey", result)

Python 2.7:

import sys
import redis
import StringIO
import gzip

redisConn = redis.StrictRedis(host="127.0.0.1", port=6379, db=0)
myValue = "This is test data"
out = StringIO.StringIO()
gzip_s = gzip.GzipFile(fileobj=out, mode="w")
result = gzip_s.write(myValue.encode())
redisConn.set("myKey", result)

但是 Python 2.7 版本代码被破坏了我收到一个错误: 'int' 对象没有属性 'encode'

有人可以帮忙 Python 2.7 的等效代码是什么 - 我的 Python 3 版本按预期工作。

提前感谢您的帮助。

Python 2 不区分字符串和字节(即使 gzip 流像此处一样以二进制形式打开)。您可以在二进制流中写入字符串而无需对其进行编码。它有一些缺点,但在您的情况下,只需删除 .encode() 调用:

gzip_s.write(myValue)

对于 Python 2/3 不可知的代码,我会简单地做:

if bytes is str:
   # python 2, no need to do anything
   pass
else:
   # python 3+: encode string as bytes
   myValue = myValue.encode()

gzip_s.write(myValue)

编辑:因为您似乎发出命令 redisConn.set("myKey", result),请不要忘记调用:

gzip_s.close()

在此之前,或者不能保证文件被完全刷新。

这是 Python 2.7 的完整工作示例。请注意 gzip_s.write() returns 写入的字节数,因此您的代码将一个 int 传递给 redisConn.set("myKey", result)。此外,如果您需要存储非 ASCII 数据,您可能 应该 显式编码和解码数据以避免意外 encoding/decoding 错误。

# -*- coding: utf-8 -*-
import redis
import StringIO
import gzip

redis_cxn = redis.StrictRedis(host='127.0.0.1', port=6379, db=0)

test_data = u'This is some test data with a non-ASCII character: ñ'
print 'Test data:\n    ', test_data

out_file = StringIO.StringIO()

gzip_file = gzip.GzipFile(fileobj=out_file, mode='wb')

# If you don't encode the data yourself, it will be implicitly encoded as
# ASCII.
gzip_file.write(test_data.encode('utf-8'))

gzip_file.close()

# Get the bytes written to the underlying file object
value = out_file.getvalue()

print 'Setting value in Redis'
redis_cxn.set('key', value)

print 'Getting value from Redis'
retrieved_value = redis_cxn.get('key')

assert retrieved_value == value

in_file = StringIO.StringIO()
in_file.write(retrieved_value)
in_file.seek(0)

gzip_file = gzip.GzipFile(fileobj=in_file, mode='rb')
retrieved_data = gzip_file.read()
retrieved_data = retrieved_data.decode('utf-8')
gzip_file.close()

assert retrieved_data == test_data
print 'Data retrieved from Redis and unzippped:\n    ', test_data