Telethon结合Redis缓存:TLObject从JSON格式还原的实现问题
Telethon结合Redis缓存:TLObject从JSON格式还原的实现问题
嘿,我之前做Telethon项目的时候也碰到过一模一样的问题!一开始自己手动转JSON存Redis,取回来发现嵌套的子对象全是字典,根本没法直接用TLObject的方法。后来摸索出两个靠谱的方案,给你唠唠:
方案一:用Telethon内置的字节序列化(推荐)
其实Telethon本身就给TLObject提供了原生的序列化/反序列化方法,比转JSON要高效得多,还能完美保留所有嵌套结构,根本不用自己处理子对象的问题。
具体操作很简单:
- 序列化TLObject成字节,存到Redis:
# 假设obj是你要缓存的TLObject实例,redis_client是你的Redis客户端连接 obj_bytes = obj.to_bytes() redis_client.set("your_cache_key", obj_bytes)
- 从Redis取出字节,还原成TLObject:
from telethon.tl.types import deserialize cached_bytes = redis_client.get("your_cache_key") if cached_bytes: # 这里需要传入Telethon客户端的TL schema,直接用client.tl就行 restored_obj = deserialize(client.tl, cached_bytes)
这个方法是官方最推荐的,完全不会有嵌套对象丢失类型的问题,性能也比JSON好不少。
方案二:如果一定要用JSON,自己写递归转换逻辑
要是你因为某些原因必须用JSON格式存储(比如要手动查看缓存内容),那就得自己写个递归函数,遍历JSON字典,把带_字段的字典转换成对应的TLObject,包括嵌套的子对象。
示例代码如下:
from telethon.tl.types import TLObject def json_dict_to_tlobj(client, json_data): # 处理列表类型 if isinstance(json_data, list): return [json_dict_to_tlobj(client, item) for item in json_data] # 处理字典类型 elif isinstance(json_data, dict): # 检查是否是TLObject的JSON表示(带"_"字段) if "_" in json_data: tl_type_name = json_data["_"] # 从客户端的TL schema里获取对应的类 tl_class = client.tl.types.get(tl_type_name) if not tl_class: # 如果找不到对应类,就返回原字典 return json_data # 递归处理每个字段,跳过"_"本身 processed_fields = { key: json_dict_to_tlobj(client, value) for key, value in json_data.items() if key != "_" } # 创建TLObject实例 return tl_class(**processed_fields) else: # 普通字典,递归处理每个值 return {k: json_dict_to_tlobj(client, v) for k, v in json_data.items()} # 非容器类型直接返回 else: return json_data
使用的时候,把从Redis取出来的JSON字符串转成字典后,传给这个函数就行:
import json cached_json_str = redis_client.get("your_cache_key") if cached_json_str: json_dict = json.loads(cached_json_str) restored_obj = json_dict_to_tlobj(client, json_dict)
为啥你之前的方法不行?
你说能根据_字段找到父类,但子字典没转成TLObject,就是因为没有递归遍历所有嵌套的层级——TLObject转成JSON后,所有嵌套的子TLObject也会变成带_的字典,必须一层一层遍历处理,才能把所有嵌套对象都还原成TLObject实例。
备注:内容来源于stack exchange,提问作者Meowth Pxnk
相关产品推荐
相关产品推荐

