定义采用 Python 的 Lambda 函数处理程序 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

定义采用 Python 的 Lambda 函数处理程序

Lambda 函数处理程序是函数代码中处理事件的方法。当调用函数时,Lambda 运行处理程序方法。您的函数会一直运行,直到处理程序返回响应、退出或超时。

在 Python 中创建函数处理程序时,可以使用以下一般语法:

def handler_name(event, context): ... return some_value

命名

在创建 Lambda 函数时指定的 Lambda 函数处理程序名称来自以下内容:

  • Lambda 处理程序函数所在的文件名称。

  • Python 处理程序函数的名称。

函数处理程序可随意命名;但是,在 Lambda 控制台上的默认名称为 lambda_function.lambda_handler。此功能处理程序名称将函数名称表示为 (lambda_handler),存储处理程序代码的文件位于 (lambda_function.py)。

如果您在控制台中使用不同的文件名或函数处理程序名称创建函数,则必须编辑默认处理程序名称。

更改函数处理程序名称(控制台)
  1. 打开 Lambda 控制台的函数页面,然后选择一个函数。

  2. 选择节点选项卡。

  3. 向下滚动到运行时设置窗格并选择编辑

  4. 处理程序中,输入函数处理程序的新名称。

  5. 选择保存

工作方式

当 Lambda 调用函数处理程序时,Lambda 运行时会将两个参数传送给函数处理程序:

  • 第一个参数是 事件对象。事件是 JSON 格式的文档,其中包含要处理的 Lambda 函数的数据。Lambda 运行时将事件转换为一个对象,并将该对象传递给函数代码。它通常是 Python dict 类型。也可以是 liststrintfloat、或 NoneType 类型。

    事件对象包含来自调用服务的信息。在调用函数时,可以确定事件的结构和内容。当 Amazon 服务调用函数时,该服务会定义事件结构。有关 Amazon 服务中的事件的更多信息,请参阅 使用来自其 Amazon 他服务的事件调用 Lambda

  • 第二个参数是 上下文对象。在运行时由 Lambda 将上下文对象传递给函数。此对象提供的方法和属性包含有关调用、函数和运行时环境的信息。

返回值

(可选)处理程序可返回值。返回值所发生的状态取决于调用函数的调用类型服务。例如:

  • 如果您使用 RequestResponse 调用类型(例如 同步调用 Lambda 函数),Amazon Lambda 会将 Python 函数调用的结果返回到调用 Lambda 函数的客户端(在对调用请求的 HTTP 响应中,序列化为 JSON)。例如,Amazon Lambda 控制台使用 RequestResponse 调用类型,因此当您使用控制台调用函数时,控制台将显示返回的值。

  • 如果处理程序返回 json.dumps 无法序列化的对象,则运行时返回错误。

  • 如果处理程序返回 None(就像不具有 return 语句的 Python 函数隐式执行的那样),则运行时返回 null

  • 如果您使用 Event 调用类型(一种异步调用),则该值将被丢弃。

注意

在 Python 3.9 及更高版本中,Lambda 在错误响应中包含调用的 requestId。

示例

以下部分介绍了可以与 Lambda 结合使用的 Python 函数的示例。如果您使用 Lambda 控制台编写函数,无需附加 zip 归档文件即可运行本部分中的功能。这些函数使用标准 Python 库,这些库位于您选择的 Lambda 运行时中。有关更多信息,请参阅 部署程序包

返回消息

以下示例显示了名为 lambda_handler 的函数。该函数接受用户输入名字和姓氏,并从它接收为输入的事件返回包含数据的消息。

def lambda_handler(event, context): message = 'Hello {} {}!'.format(event['first_name'], event['last_name']) return { 'message' : message }

您可以使用以下事件数据 调用函数:

{ "first_name": "John", "last_name": "Smith" }

响应显示作为输入传递的事件数据:

{ "message": "Hello John Smith!" }

解析响应

以下示例显示了名为 lambda_handler 的函数。该函数在运行时使用 Lambda 传递的事件数据。它解析 JSON 响应中 AWS_REGION 返回的 环境变量

import os import json def lambda_handler(event, context): json_region = os.environ['AWS_REGION'] return { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": json.dumps({ "Region ": json_region }) }

您可以使用任何事件数据 调用函数:

{ "key1": "value1", "key2": "value2", "key3": "value3" }

Lambda 运行时会在初始化过程中设置多个环境变量。有关在运行时响应中返回的环境变量的更多信息,请参阅 使用 Lambda 环境变量配置代码中的值

本示例中的函数取决于 Invoke API 的成功响应(200 中)。有关调用 API 状态的更多信息,请参阅调用响应语法。

返回计算

以下示例显示了名为 lambda_handler 的函数。该函数接受用户输入并将计算返回给用户。有关此示例的更多信息,请参阅 aws-doc-sdk-examples GitHub 存储库

import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): ... result = None action = event.get('action') if action == 'increment': result = event.get('number', 0) + 1 logger.info('Calculated result of %s', result) else: logger.error("%s is not a valid action.", action) response = {'result': result} return response

您可以使用以下事件数据 调用函数:

{ "action": "increment", "number": 3 }

Python Lambda 函数的代码最佳实践

在构建 Lambda 函数时,请遵循以下列表中的指南,采用最佳编码实践:

  • 从核心逻辑中分离 Lambda 处理程序。这样您可以创建更容易进行单元测试的函数。例如,在 Python 中,如下所示:

    def lambda_handler(event, context): foo = event['foo'] bar = event['bar'] result = my_lambda_function(foo, bar) def my_lambda_function(foo, bar): // MyLambdaFunction logic here
  • 控制函数部署程序包中的依赖关系。Amazon Lambda 执行环境包含许多库。对于 Node.js 和 Python 运行时,其中包括 Amazon SDK。Lambda 会定期更新这些库,以支持最新的功能组合和安全更新。这些更新可能会使 Lambda 函数的行为发生细微变化。要完全控制您的函数所用的依赖项,请使用部署程序包来打包所有依赖项。

  • 将依赖关系的复杂性降至最低。首选在执行环境启动时可以快速加载的更简单的框架。

  • 将部署程序包大小精简为只包含运行时必要的部分。这样会减少调用前下载和解压缩部署程序包所需的时间。

  • 利用执行环境重用来提高函数性能。连接软件开发工具包 (SDK) 客户端和函数处理程序之外的数据库,并在 /tmp 目录中本地缓存静态资产。由函数的同一实例处理的后续调用可重用这些资源。这样就可以通过缩短函数运行时间来节省成本。

    为了避免调用之间潜在的数据泄露,请不要使用执行环境来存储用户数据、事件或其他具有安全影响的信息。如果您的函数依赖于无法存储在处理程序的内存中的可变状态,请考虑为每个用户创建单独的函数或单独的函数版本。

  • 使用 keep-alive 指令来维护持久连接。Lambda 会随着时间的推移清除空闲连接。在调用函数时尝试重用空闲连接会导致连接错误。要维护您的持久连接,请使用与运行时关联的 keep-alive 指令。有关示例,请参阅在 Node.js 中通过 Keep-Alive 重用连接

  • 使用环境变量将操作参数传递给函数。例如,您在写入 Amazon S3 存储桶时,不应对要写入的存储桶名称进行硬编码,而应将存储桶名称配置为环境变量。

  • 避免在 Lambda 函数中使用递归调用,在这种情况下,函数会调用自己或启动可能再次调用该函数的进程。这可能会导致意想不到的函数调用量和升级成本。如果您看到意外的调用量,请立即将函数保留并发设置为 0 来限制对函数的所有调用,同时更新代码。

  • Lambda 函数代码中不要使用非正式的非公有 API。对于 Amazon Lambda 托管式运行时,Lambda 会定期为 Lambda 的内部 API 应用安全性和功能更新。这些内部 API 更新可能不能向后兼容,会导致意外后果,例如,假设您的函数依赖于这些非公有 API,则调用会失败。请参阅 API 参考以查看公开发布的 API 列表。

  • 编写幂等代码。为您的函数编写幂等代码可确保以相同的方式处理重复事件。您的代码应该正确验证事件并优雅地处理重复事件。有关更多信息,请参阅如何使我的 Lambda 函数具有幂等性?