Python __bytes__() 方法

Python __bytes__() 语法

__bytes__() 是 Python 的一个特殊方法(又称 “魔法方法” 或 “双下划线方法”),当使用内置的 bytes() 函数(不带 encoding 参数)来转换一个对象时,Python 会自动调用这个方法。

__bytes__() 方法允许你自定义对象如何被转换为 bytes 对象。__bytes__() 主要用于需要将对象表示为原始字节流的场景,例如网络传输、文件存储、加密操作等。

语法:

class MyObject:
    def __bytes__(self):
        # 返回一个 bytes 对象
        return b'xxx'

说明:

__bytes__() 方法不接收任何参数(除了 self)。它必须返回一个 bytes 对象。如果返回其他类型,将会引发 TypeError 异常。

对于 __bytes__() 方法,小伙伴们要清楚以下 2 点。

  • 当你在一个自定义对象 obj 上调用 bytes(obj) 而不提供编码参数时,Python 会自动查找并执行 obj.__bytes__() 方法。
  • 如果一个类没有定义 __bytes__() 方法,并且你尝试使用 bytes() 函数转换其实例,则 Python 会尝试使用 __str__() 方法,将其结果编码为字节串(通常是默认编码 utf-8)。如果 __str__() 也不存在,或者编码失败,就会直接报错。

Python __bytes__() 摘要

属于 Python 魔法方法
使用频率
官方文档 查看
相关方法 __str__()

Python __bytes__() 示例

接下来,我们通过几个简单的例子来讲解一下 Python __bytes__() 方法是如何使用的。

示例 1:__bytes__() 基本用法

class MyData:
    def __init__(self, value):
        self.value = value

    def __bytes__(self):
        # 将对象的字符串表示编码为 UTF-8 字节
        return str(self.value).encode('utf-8')

data1 = MyData('Hello, lvye!')
result1 = bytes(data1)
print(result1)
print(type(result1))

data2 = MyData(666)
result2 = bytes(data2)
print(result2)
print(type(result2))

运行结果如下。

b'Hello, lvye!'
<class 'bytes'>
b'666'
<class 'bytes'>

分析:

在这个例子中,我们定义了一个 MyData 类,并为其实现了 __bytes__() 方法。该方法将 self.value 转换为字符串,然后使用 encode() 方法将其编码为 UTF-8 字节序列并返回。

当我们对 MyData 的实例调用 bytes() 函数时,Python 会自动调用 MyData 类的 __bytes__() 方法来获取其字节表示。

示例 2:__bytes__() 处理不同数据类型

class DataConverter:
    def __init__(self, data):
        self.data = data

    def __bytes__(self):
        if isinstance(self.data, str):
            return self.data.encode('utf-8')
        elif isinstance(self.data, int):
            return self.data.to_bytes((self.data.bit_length() + 7) // 8, 'big')
        elif isinstance(self.data, list):
            # 将列表中的每个元素转换为字符串并连接,然后编码
            return ','.join(map(str, self.data)).encode('utf-8')
        else:
            raise TypeError(f"Cannot convert type {type(self.data)} to bytes")

# 字符串数据
converter_str = DataConverter('lvyenet')
print(bytes(converter_str))

# 整数数据
converter_int = DataConverter(255)
print(bytes(converter_int))

# 列表数据
converter_list = DataConverter(['apple', 666, True])
print(bytes(converter_list))

运行结果如下。

b'lvyenet'
b'\xff'
b'apple,666,True'

分析:

在 DataConverter 类中,我们手动实现了 __bytes__() 方法。该方法会根据 self.data 的类型执行不同的转换逻辑:

  • 对于字符串,直接进行 UTF-8 编码。
  • 对于整数,使用 to_bytes() 方法将其转换为字节序列。to_bytes() 方法需要 2 个参数:所需字节长度(此处根据整数的比特长度计算)和字节顺序('big' 或 'little')。
  • 对于列表,将列表中的所有元素转换为字符串后用逗号连接,再进行 UTF-8 编码。

示例 3:没有实现 __bytes__() 方法

class MyObject:
    def __init__(self, name):
        self.name = name

try:
    obj = MyObject('Test')
    result = bytes(obj)
    print(result)
except TypeError as e:
    print(e)

运行结果如下。

(报错)cannot convert 'MyObject' object to bytes

分析:

如果一个类没有定义 __bytes__() 方法,那么当我们尝试将其实例转换为字节序列时,会直接报错。

上一篇: __repr__()

下一篇: __format__()

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号