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

使用jsonpickle序列化Telegram对象后反序列化出现AttributeError

问题:Telegram Update对象序列化后反序列化丢失属性

我需要在多个AWS Lambda函数之间传递Telegram消息对象,因此需要对其进行序列化。尝试使用jsonpickle模块,但反序列化后调用属性时遇到AttributeError。

未序列化时的正常运行情况

>>> from telegram import Bot, Update
>>> bot = Bot('XXXXXXXX')
>>> update = Update.de_json({...}, bot)
>>> type(update)
<class 'telegram.update.Update'>
>>> dir(update)
['ALL_TYPES', 'CALLBACK_QUERY', 'CHANNEL_POST', 'CHAT_JOIN_REQUEST', 'CHAT_MEMBER', 'CHOSEN_INLINE_RESULT', 'EDITED_CHANNEL_POST', 'EDITED_MESSAGE', 'INLINE_QUERY', 'MESSAGE', 'MY_CHAT_MEMBER', 'POLL', 'POLL_ANSWER', 'PRE_CHECKOUT_QUERY', 'SHIPPING_QUERY', '__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__slots__', '__str__', '__subclasshook__', '_effective_chat', '_effective_message', '_effective_user', '_id_attrs', '_parse_data', 'callback_query', 'channel_post', 'chat_join_request', 'chat_member', 'chosen_inline_result', 'de_json', 'de_list', 'edited_channel_post', 'edited_message', 'effective_chat', 'effective_message', 'effective_user', 'inline_query', 'message', 'my_chat_member', 'poll', 'poll_answer', 'pre_checkout_query', 'shipping_query', 'to_dict', 'to_json', 'update_id']
>>> update.message.reply_text('hello')
<telegram.message.Message object at 0x7ff6282da788>

序列化与反序列化过程

尝试序列化update对象:

>>> e_update = jsonpickle.encode(update)
>>> e_update
'{"py/object": "telegram.update.Update"}'

反序列化后调用属性出错:

>>> d_update = jsonpickle.decode(e_update)
>>> type(d_update)
<class 'telegram.update.Update'>
>>> dir(d_update)
['ALL_TYPES', 'CALLBACK_QUERY', 'CHANNEL_POST', 'CHAT_JOIN_REQUEST', 'CHAT_MEMBER', 'CHOSEN_INLINE_RESULT', 'EDITED_CHANNEL_POST', 'EDITED_MESSAGE', 'INLINE_QUERY', 'MESSAGE', 'MY_CHAT_MEMBER', 'POLL', 'POLL_ANSWER', 'PRE_CHECKOUT_QUERY', 'SHIPPING_QUERY', '__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__slots__', '__str__', '__subclasshook__', '_effective_chat', '_effective_message', '_effective_user', '_id_attrs', '_parse_data', 'callback_query', 'channel_post', 'chat_join_request', 'chat_member', 'chosen_inline_result', 'de_json', 'de_list', 'edited_channel_post', 'edited_message', 'effective_chat', 'effective_message', 'effective_user', 'inline_query', 'message', 'my_chat_member', 'poll', 'poll_answer', 'pre_checkout_query', 'shipping_query', 'to_dict', 'to_json', 'update_id']
>>> d_update.ALL_TYPES
['message', 'edited_message', 'channel_post', 'edited_channel_post', 'inline_query', 'chosen_inline_result', 'callback_query', 'shipping_query', 'pre_checkout_query', 'poll', 'poll_answer', 'my_chat_member', 'chat_member', 'chat_join_request']
>>> d_update.message
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: message

可以看到,jsonpickle处理后,虽然对象类型正确,但实例属性全部丢失,无法调用message等属性。


解决方案思路

1. 改用Telegram官方提供的序列化方法

Telegram Bot库的Update对象本身就提供了to_dict()和to_json()方法,这是官方为序列化设计的,能正确保留所有实例数据:

# 序列化
update_dict = update.to_dict()
# 或者转成JSON字符串
update_json = update.to_json()

# 在另一个Lambda中反序列化
bot = Bot('XXXXXXXX')
d_update = Update.de_json(update_dict, bot)
# 如果是JSON字符串,先转成dict:import json; update_dict = json.loads(update_json)

这样处理后,d_update会和原对象一样拥有所有属性,能正常调用d_update.message。

2. 为什么jsonpickle不行?

从你得到的序列化结果'{"py/object": "telegram.update.Update"}'可以看出,jsonpickle只序列化了对象的类型,没有序列化实例的属性数据。这是因为Telegram Bot库的对象可能使用了__slots__或者自定义的属性存储方式,jsonpickle默认配置无法正确识别并序列化这些属性。

如果一定要用jsonpickle,需要调整其配置(比如启用pickle兼容模式),但官方方法显然更可靠,没必要折腾。

3. Lambda间传递的注意事项

  • 如果用JSON字符串传递,确保在Lambda之间传递时是标准JSON格式,避免编码问题。
  • 不需要传递整个Bot对象,每个Lambda可以自己初始化Bot实例,只传递Update的字典/JSON数据即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:11:05