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__() 方法,那么当我们尝试将其实例转换为字节序列时,会直接报错。
