我编写了一个类来表示带有base64编码字符串的LZMA压缩数据:
from base64 import b64decode
from lzma import LZMADecompressor
class B64LZMA(str):
"""A string of base64 encoded, LZMA compressed data."""
def __bytes__(self):
"""Returns the decompressed data."""
return LZMADecompressor().decompress(b64decode(self.encode()))
def __str__(self):
"""Returns the string decoded from __bytes__."""
return bytes(self).decode()
TEST_STR = B64LZMA('/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQALSGVsbG8gd29ybGQuAGt+oFiSvoAYAAEkDKYY2NgftvN9AQAAAAAEWVo=')
if __name__ == '__main__':
print(TEST_STR)
虽然这在ArchLinux上的python 3.6中运行得很好,但我在Debian 8上的python 3.4上得到以下错误:
Traceback (most recent call last):
File "./test.py", line 22, in <module>
print(TEST_STR)
File "./test.py", line 16, in __str__
return bytes(self).decode()
TypeError: string argument without an encoding
为什么python 3.4和python 3.6之间的行为存在差异?如何在python 3.4中使用上述类?
更新
要验证的脚本:
#! /usr/bin/env python3
from base64 import b64decode
from lzma import LZMADecompressor
from sys import version
class B64LZMA(str):
"""A string of base64 encoded, LZMA compressed data."""
def __bytes__(self):
"""Returns the decompressed data."""
return LZMADecompressor().decompress(b64decode(self.encode()))
def __str__(self):
"""Returns the string decoded from __bytes__."""
return bytes(self).decode()
TEST_STR = B64LZMA('/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQALSGVsbG8gd29ybGQuAGt+oFiSvoAYAAEkDKYY2NgftvN9AQAAAAAEWVo=')
if __name__ == '__main__':
print(version)
print(TEST_STR)
SHA-256总和:64513a7508b20dda5cc26c37fa4dc8f516369937569833bb0957c10ea887ae00
在Debian 8上使用python 3.4输出:
$ ./test.py
3.4.2 (default, Oct 8 2014, 10:45:20)
[GCC 4.9.1]
Traceback (most recent call last):
File "./test.py", line 24, in <module>
print(TEST_STR)
File "./test.py", line 17, in __str__
return bytes(self).decode()
TypeError: string argument without an encoding
在ArchLinux上使用python 3.6输出:
$ ./test.py
3.6.4 (default, Dec 23 2017, 19:07:07)
[GCC 7.2.1 20171128]
Hello world.
答案 0 :(得分:2)
好的,在python 3.4中__bytes__
继承自字符串的对象似乎无法识别bytes()
方法。
通过明确调用__str__()
更改__bytes__()
方法解决了问题:
def __str__(self):
"""Returns the string decoded from __bytes__."""
return self.__bytes__().decode()