关于 n8n-code-python
这份参考技能说明如何在 n8n 2.0 及更高版本的 Code 节点中编写原生 Python,面向需要在工作流中使用 Python 的作者。内容重点包括输入模式、沙箱限制、返回结构,以及可能导致数据静默透传的失败情形。
主要功能
- 01原生 Python 输入变量与模式
- 02导入白名单与沙箱限制
- 03按模式区分返回结构
- 04旧版 Pyodide 迁移说明
- 05错误行为与测试清单
适用场景
- 01迁移旧版 Python Code 节点代码
- 02筛选或转换工作流项目
- 03排查导入受限和返回错误
- 04n8n 升级后检查输出
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ czlonkowski/ n8n-skills --skill n8n-code-python安装后在 Claude Code 中输入/n8n-code-python确认已加载。
附带文件COMMON_PATTERNS.mdREADME.md
详细介绍
Python 代码节点(原生)
从 n8n 2.0 起,Code 节点中的 Python 会作为任务运行器中的原生 Python运行(language: "pythonNative")。旧版 Pyodide「Python (Beta)」已移除,随之消失的还有它提供的所有 n8n 辅助工具:
_input、_json、_node、_now、_today 和 _jmespath 现在都会引发 NameError。从旧模板、论坛帖子或较早文档中复制的代码通常会因此无法运行。
优先使用 JavaScript——现在更是如此
原生 Python 提供两个变量和纯 Python,默认不允许导入任何模块:没有
json、datetime 或 re。所有 n8n 专属功能($('Node')、$jmespath、Luxon、
this.helpers.httpRequest、静态数据)都只存在于 JavaScript 中。只有在用户明确要求时才使用 Python。即便如此,也要先确认表达式、Edit Fields 或原生节点(Crypto、Date & Time、HTML、XML)能否完成任务。请参阅 n8n-code-javascript 和 n8n-expression-syntax 中的转换把关说明。
快速开始
# Run Once for All Items (default mode)
return [
{"json": {"name": it["json"]["name"], "revenue": it["json"]["revenue"]}}
for it in _items
if it["json"].get("active")
]
# Run Once for Each Item
row = _item["json"]
return {"json": {**row, "name_upper": (row.get("name") or "").upper()}}
节点配置:{"language": "pythonNative", "mode": "runOnceForAllItems" | "runOnceForEachItem", "pythonCode": "..."},适用于 n8n-nodes-base.code 类型的 version 2。
仅有的输入:_items 和 _item
| 模式 | 变量 | 结构 |
|---|---|---|
| Run Once for All Items | _items | 由普通字典 {"json": {...}, "pairedItem": {...}} 组成的 list |
| Run Once for Each Item | _item | 一个普通字典 {"json": {...}, "pairedItem": {...}} |
- 每个变量仅在对应模式下存在。在逐项模式下使用
_items(或在所有项模式下使用_item)会引发NameError。 - **只能通过字典访问。**使用
it["json"]["name"]或it["json"].get("name")。it.json.name会引发AttributeError: 'dict' object has no attribute 'json'。 - **无法访问其他节点。**没有
_node/$('Node')的等效功能。如果需要另一个分支的数据,请先用 Merge 将其引入,或改用 JavaScript。 - Webhook 载荷位于
["body"]下:_items[0]["json"].get("body", {}).get("email")。 - 二进制数据不在本文介绍范围内。请在 JavaScript 中读取和写入二进制数据(参见 n8n-binary-and-data)。
- **pairedItem:**返回
_items/_item会保留它。新建字典时,如果下游使用$('Node').item,请在每个返回项中添加"pairedItem": {"item": i}。原生 Python 目前尚未验证此功能,请先运行测试再依赖它。 - 缺失的键:优先使用
.get(key, default)。row["missing"]会引发KeyError。
旧版代码迁移表:
| 旧版(Pyodide) | 原生版本 |
|---|---|
_input.all() | _items |
_input.first()["json"] | _items[0]["json"](先检查 if _items) |
_input.item / _json | _item / _item["json"] |
_node["X"] | 不可用:在上游使用 Merge,或改用 JS |
_now、_today | 不可用:通过 Edit Fields 传入 {{ $now.toISO() }},或改用 JS |
_jmespath(data, q) | 不可用:在表达式中使用 $jmespath,或使用推导式 |
item.json.field | item["json"]["field"] |
导入:默认禁止
每个 import(标准库和第三方库)都会在代码运行之前通过允许列表进行检查。默认允许列表为空,因此即使是 import json 也会导致整个节点被拒绝:
Security violations detected
Line 1: Import of standard library module 'json' is disallowed. Allowed stdlib modules: none
- **n8n Cloud:**完全不允许导入。
- **自托管:**管理员可以在 task-runner 配置中将模块加入允许列表(参见 n8n-self-hosting →
TASK_RUNNERS.md)。因此,某些实例允许使用json、datetime和re,但大多数不允许。 - **默认编写不依赖导入的代码。**如果导入确实能提供帮助,请先确认:运行一个单行测试节点
import json+return [{"json": {"ok": True}}],或询问用户。切勿想当然。 - 不使用导入:在上游解析 JSON 字符串(在 Edit Fields 中使用
{{ JSON.parse($json.payload) }})。使用 Date & Time 节点或表达式中的 Luxon 进行日期运算。ISO-8601 字符串仍可作为普通字符串正确比较和排序。使用 Crypto 节点进行哈希。 - 除非管理员构建了自定义 runner 镜像,否则绝不会提供
requests、pandas和numpy。HTTP 请求请使用 HTTP Request 节点。
沙盒限制(即使不导入也会失败)
| 你编写的内容 | 结果 | 替代方案 |
|---|---|---|
eval、exec、compile、open、input、type、getattr、setattr、hasattr、vars、dir、globals、locals、object、memoryview、breakpoint | NameError: name 'type' is not defined(运行时) | isinstance(x, dict);key in d / d.get(key) |
class Foo: ... | __build_class__ not found(运行时) | 字典 + 函数 |
x.__class__、"{0.__class__}".format(x)、__import__("json") | Security violations detected(整个节点会在运行前被拒绝) | — |
函数内的 global counter | NameError: name 'counter' is not defined,因为代码在包装函数内运行 | nonlocal counter |
普通 Python 中的其他功能都可以使用(已验证):推导式、生成器、lambda、闭包、递归、try/except、f 字符串 / .format() / %、sorted/min/max/sum/any/all/enumerate/zip/round、集合、isinstance、print()(输出会显示在浏览器控制台中)。
返回值形状(已验证)
在 n8n 2.38.5 上观察到。以下自动包装和透传行为没有文档说明,后续版本中可能会改变。升级 n8n 后,请通过测试运行再次确认。
Run Once for All Items
| 返回值 | 结果 |
|---|---|
[{"json": {...}}, ...] | 标准形式,N 个项目 |
[{...}, ...](普通字典) | 自动包装到 json 下,N 个项目 |
{"json": {...}} 或单个普通字典 | 1 个项目 |
_items(原地修改) | 透传并保留你的修改 |
None / 无 return | 错误 Cannot read properties of null (reading 'json') |
Run Once for Each Item
| 返回值 | 结果 |
|---|---|
{"json": {...}}、普通字典或 _item | 1 个项目 |
None | 该项目会被丢弃(内置筛选行为) |
| 列表 | 错误 A 'json' property isn't a dictionary [item 0] |
输出时的值转换:tuple 会变成列表,set 会变成字符串 "{1, 2}",datetime 会变成 str(dt)("2026-09-16 10:18:00.025792",而非 ISO 格式)。请显式转换(sorted(s)、dt.isoformat())。
在所有项目模式下,建议始终使用显式的 [{"json": ...}];在每个项目模式下,建议始终使用 {"json": ...}。自动包装虽然有效,但显式形式能让后续阅读代码的人一目了然。
Errors 和 onError
简单的 raise ValueError("bad row") 会使节点失败,并显示该消息。当节点使用 onError 的 continue 模式时,三种失败类型的表现各不相同(已验证):
| 失败 | continueErrorOutput | continueRegularOutput |
|---|---|---|
运行时异常(raise、KeyError、NameError、禁止使用的内置函数) | 错误输出(main[1])上出现 {"error": "<message>"} ✅ | 主输出上出现 {"error": "<message>"} |
静态拒绝(Security violations detected:导入、dunder) | 节点标记为失败,但未经更改的输入项会通过成功输出;main[1] 保持为空 | 未经更改的输入项通过主输出 |
返回形状错误(逐项模式下返回列表,全项模式下返回 None) | 同上:未经更改的输入通过成功输出 | 同上 |
后两种情况会造成静默数据陷阱:下游节点会收到未经处理的输入,就像代码已经运行过一样,而且执行仍显示成功。没有错误分支能捕获它们。请避免这些情况(未经确认不要导入模块,并确保返回形状正确),并通过真实测试运行进行确认,检查 Code 节点的状态和输出(参见 n8n-error-handling)。
其他消息:
Python runner unavailable: Python 3 is missing from this system:自托管实例没有 Python 任务运行器(官方镜像未附带)。这是基础设施问题,不是代码问题。参见 n8n-self-hosting →TASK_RUNNERS.md。validate_node/validate_workflow能捕获一些 Python 错误(import requests、缺少return、return None),但无法捕获_input/_json、点号访问、被阻止的标准库导入、dunder 访问或类。测试执行是唯一可靠的检查方式。
性能
每个 Python Code 节点大约耗时 0.4 秒(运行器刚启动时约为 1 秒),明显慢于 JS Code 节点或表达式。应使用 Run Once for All Items 模式处理列表,而不是逐项处理;如果一个小型 Python 节点就能完成工作,就不要串联多个节点。
检查清单
- 用户确实要求使用 Python。否则使用 JS、表达式或原生节点。
- 模式与变量匹配:
_items(所有项)/_item(每项)。 - 只访问字典。不使用
_input、_json、_node、_now或_jmespath。 - 未经确认已在此实例的允许列表中,不使用
import。 - 不使用类、
type()、getattr/hasattr或 dunder。使用nonlocal而非global。 - 返回形状符合模式。显式转换集合和日期时间。
- 已运行真实测试并检查输出项(仅靠验证无法发现上述陷阱)。
参考
- COMMON_PATTERNS.md:12 种无需导入模块的模式,均已在实际运行的 n8n 实例上验证(筛选、聚合、分组、去重、前 N 项、扁平化、验证、丢弃项、文本报告、安全的嵌套访问、累计总和、ISO 时间戳)。
相关技能
- n8n-code-javascript:Code 节点的默认选择,支持所有 n8n 辅助函数。
- n8n-expression-syntax:
$jmespath、Luxon 和转换门卫,通常比任何 Code 节点都更合适。 - n8n-code-tool:在 AI Agent 自定义代码工具(
_query,返回字符串)中使用 Python。 - n8n-error-handling:连接错误输出;以及上述直通陷阱。
- n8n-self-hosting:启用 Python 任务运行器并将模块加入允许列表。