You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.4与3.6中TypeError差异问题及兼容方案问询

Why does this B64LZMA class fail in Python 3.4 but work in 3.6, and how to make it compatible?

Let's break down the issue and fix it step by step.

The Problem

You've got a B64LZMA class that extends str to handle base64-encoded LZMA data. It works fine in Python 3.6+ but throws TypeError: string argument without an encoding in Python 3.4. The problematic line is in the __str__ method:

return bytes(self).decode()

Why the Behavior Difference?

The root cause is a change in how Python's bytes() function handles subclasses of str:

  • Python 3.4: When you call bytes(obj) on a subclass of str, Python treats it as a regular string. It expects you to provide an encoding argument (like bytes(obj, 'utf-8')) and does not invoke the object's __bytes__ method. This is why you get the "string argument without an encoding" error—Python thinks you're trying to convert a string to bytes, not using your custom __bytes__ implementation.
  • Python 3.6+: The bytes() function was updated to prioritize calling an object's __bytes__ method first, even if the object is a subclass of str. So bytes(self) correctly triggers your custom decompression logic instead of treating self as a plain string.

How to Fix Compatibility with Python 3.4

To make the code work across both versions, avoid relying on bytes(self) to invoke your __bytes__ method. Instead, call __bytes__() directly in the __str__ method:

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__."""
        # Directly call __bytes__() instead of using bytes(self)
        return self.__bytes__().decode()

TEST_STR = B64LZMA('/Td6WFoAAATm1rRGAgAhARYAAAB0L+WjAQALSGVsbG8gd29ybGQuAGt+oFiSvoAYAAEkDKYY2NgftvN9AQAAAAAEWVo=')
if __name__ == '__main__':
    print(TEST_STR)

Alternatively, you could rewrite the __str__ method to compute the decoded string directly without relying on __bytes__, but calling self.__bytes__() keeps your code DRY (Don't Repeat Yourself) and maintains separation of concerns.

This change ensures that both Python 3.4 and 3.6+ use your custom decompression logic correctly, avoiding the TypeError in older versions.

内容的提问来源于stack exchange,提问作者user3515670

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:00:12