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

使用pickle反序列化Python函数时触发AttributeError报错求助

问题:Pickle反序列化函数时触发AttributeError(AWS Lambda环境)

我在Jupyter Notebook中编写了customer_transform函数,使用pickle将其序列化后存储到AWS S3中。当在AWS Lambda环境中从S3读取并反序列化该函数时,触发如下AttributeError:

{
  "errorMessage": "Can't get attribute 'customer_transform' on <module '__main__' from '/var/runtime/bootstrap.py'>",
  "errorType": "AttributeError",
  "stackTrace": [
    "  File \"/var/task/on_demand_dataset_load_and_transform/handler.py\", line 14, in lambda_handler
    return transform_data(load_response, udf_s3_key)
",
    "  File \"/var/task/on_demand_dataset_load_and_transform/transform_data.py\", line 26, in transform_data
    udf = pickle.loads(udf_bytes)
"
  ]
}

序列化代码(Jupyter Notebook中)

def customer_transform(input):
     # 函数实现逻辑

import pickle

def serialize_func(func):
    return pickle.dumps(func)

serialized_transform = serialize_func(customer_transform)

s3_client.put_object(Body=serialized_transform, Bucket="Bucket_name", Key="key")

反序列化代码(AWS Lambda中)

udf_bytes = s3_client.get_object(Bucket="Bucket_name", Key="key")["Body"].read()

downloaded_func = pickle.loads(udf_bytes)

原因分析

Pickle序列化函数时,不会存储函数的完整代码,仅记录函数名称及其所在的模块路径。在Jupyter Notebook中,直接定义的函数默认归属__main__模块;但在AWS Lambda环境中,__main__指向的是/var/runtime/bootstrap.py,该模块中不存在customer_transform的定义,因此反序列化时会触发找不到属性的错误。

解决方案

方案1:将函数放在独立模块中(推荐)

把customer_transform函数放到独立的Python模块文件(如transform_utils.py)中,序列化和反序列化时统一从该模块导入函数,确保两端模块结构一致。

  1. 创建模块文件transform_utils.py
# transform_utils.py
def customer_transform(input):
    # 函数实现逻辑
  1. Jupyter中的序列化代码调整
from transform_utils import customer_transform
import pickle
import boto3

s3_client = boto3.client('s3')

serialized_transform = pickle.dumps(customer_transform)
s3_client.put_object(Body=serialized_transform, Bucket="Bucket_name", Key="key")
  1. AWS Lambda部署准备
    将transform_utils.py与Lambda的handler代码放在同一目录下打包部署,确保Lambda环境能找到该模块。反序列化代码无需修改,此时pickle会从transform_utils模块查找函数定义。

方案2:使用cloudpickle替代pickle

cloudpickle是pickle的增强版本,支持序列化不在模块顶层的函数(如Jupyter中直接定义的函数),无需依赖原模块结构。

  1. Jupyter中安装并使用cloudpickle序列化
!pip install cloudpickle

def customer_transform(input):
     # 函数实现逻辑

import cloudpickle
import boto3

s3_client = boto3.client('s3')
serialized_transform = cloudpickle.dumps(customer_transform)
s3_client.put_object(Body=serialized_transform, Bucket="Bucket_name", Key="key")
  1. Lambda中安装cloudpickle并反序列化
    在Lambda部署包中包含cloudpickle(可通过pip install cloudpickle -t ./安装到本地目录后打包),然后修改反序列化代码:
import cloudpickle
import boto3

s3_client = boto3.client('s3')
udf_bytes = s3_client.get_object(Bucket="Bucket_name", Key="key")["Body"].read()
downloaded_func = cloudpickle.loads(udf_bytes)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:59:50