TypeError:在3.4中没有编码但在3.6中没有编码的字符串参数

时间:2018-01-12 10:26:22

标签: python string python-3.x character-encoding

我编写了一个类来表示带有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.

1 个答案:

答案 0 :(得分:2)

好的,在python 3.4中__bytes__继承自字符串的对象似乎无法识别bytes()方法。

通过明确调用__str__()更改__bytes__()方法解决了问题:

def __str__(self):
    """Returns the string decoded from __bytes__."""
    return self.__bytes__().decode()