Bun执行python代码

我40岁了, 还在写程序。

JS 想调 Python? Bun.$ 轻松搞定。

bash 复制代码
// 1.js
import { $ } from "bun";

const result = await $`py -c "print('Hello from Python!')"`.text();
console.log(result);

三行代码, Python 就这么跑起来了。bun 1.js 走起, 终端出 Hello from Python!。


今天你会学到这些关键词

关键词 解释
Bun.$ Bun 内置的 shell 模板, 反引号里写命令直接跑
ShellError 子进程跑挂时抛的错, 带退出码和 stderr
top-level await Bun 支持模块顶层直接 await, 不用包 async
子进程 操作系统层面的进程, 跟父进程相互独立
环境变量 进程间传值的方式, Python 用 os.environ 读

凭啥能调 Python

没啥神秘的。

Python 本身就是个可执行程序。Windows 上叫 py, Mac / Linux 上叫 python3。

你打开终端敲 py hello.py, 系统就找到 Python 解释器, 把脚本喂给它跑。

Bun.$ 干的就是这事儿。区别只是: 不用打开终端, 在 JS 文件里写反引号就行。


例 1: 调外部 .py 文件

hello.py:

bash 复制代码
# hello.py
import math
import sys
import io

# 强制 stdout 用 UTF-8, 避免 Windows 终端乱码
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")


def circle_area(radius: float) -> float:
    """根据半径计算圆的面积"""
    return math.pi * radius ** 2


if __name__ == "__main__":
    r = 5
    area = circle_area(r)
    print(f"半径 {r} 的圆, 面积是 {area:.2f}")

2.js:

bash 复制代码
// 2.js
import { $ } from "bun";

try {
  const output = await $`py hello.py`.text();
  console.log(output);
} catch (error) {
  console.error("Python 脚本执行出错:", error);
}

跑一下:

bash 复制代码
bun 2.js

输出:

bash 复制代码
半径 5 的圆, 面积是 78.54

JS 这头一个 await, Python 那头 math.pi 就给你安排上了。整个流程: JS 发命令, Python 接活儿, 结果回传 JS。丝滑得很。


例 2: 给 Python 传参数

JS 这头有数据, 想喂给 Python 处理, 咋整?

最稳的方式是走环境变量 。.env() 把变量塞进子进程, Python 用 os.environ 接。安全, 简单, 跨平台。

3.js:

bash 复制代码
// 3.js
import { $ } from "bun";

try {
  const number = 7;
  const output = await $`py calc.py`
    .env({ NUMBER: String(number) })
    .text();
  console.log(output);
} catch (error) {
  console.error("出错:", error);
}

calc.py:

bash 复制代码
import sys
import io
import os

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")

n = int(os.environ.get("NUMBER", "0"))
print(f"输入 {n}, 平方是 {n ** 2}")

跑一下:

bash 复制代码
bun 3.js

输出:

bash 复制代码
输入 7, 平方是 49

数据过去, 结果回来, 干净利落。


例 3: 接 JSON 返回值

Python 算完想回传给 JS?

让它吐 JSON, Bun 这头 .json() 一接, 完事儿。跨语言传结构化数据就这么简单。

4.js:

bash 复制代码
// 4.js
import { $ } from "bun";

try {
  const data = await $`py data.py`.json();
  console.log("姓名:", data.user.name);
  console.log("年龄:", data.user.age);
} catch (error) {
  console.error("出错:", error);
}

data.py:

bash 复制代码
import sys
import io
import json

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")

result = {"user": {"name": "老王", "age": 40}}
print(json.dumps(result, ensure_ascii=False))

跑一下:

bash 复制代码
bun 4.js

输出:

bash 复制代码
姓名: 老王
年龄: 40

Python 输出 JSON, JS 这头直接拿到对象。直接 data.user.name 用, 不用解析, 丝滑得很。


例 4: 错误处理

Python 报错退出, Bun 这头会抛 ShellError。exitCode 是退出码, stderr 是错误输出。调试的时候, 这俩最有用。

5.js:

bash 复制代码
// 5.js
import { $ } from "bun";

try {
  await $`py error.py`.text();
} catch (error) {
  console.error("退出码:", error.exitCode);
  console.error("错误信息:", error.stderr.toString());
}

error.py:

bash 复制代码
# error.py
import sys
sys.stderr.write("出大事了\n")
sys.exit(1)

跑一下:

bash 复制代码
bun 5.js

输出:

bash 复制代码
退出码: 1
错误信息: 出大事了

报错信息一清二楚, 排错轻松。


Windows 编码坑

我头回在 Windows 上跑, 输出长这样:

bash 复制代码
�뾶 5 ��Բ������� 78.54

啥玩意儿? 全是问号方块。

一查才知道, Windows PowerShell 默认 GBK 编码, Python 输出 UTF-8, 字符集对不上, 就糊了。

修法贼简单, 在 Python 脚本顶上加上这几行:

bash 复制代码
import sys
import io

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")

把 stdout 强行套成 UTF-8, 谁调都不乱。这几行放任何 Python 脚本顶上都能用, 建议收藏。


写在最后

Bun.$ 这玩意儿, 用起来就一个字: 爽。

以前想在 JS 里调 Python, 得开 child_process, 拼命令, 处理流, 解析输出, 一通操作猛如虎。

现在? 一个反引号, 完事儿。

相关推荐
陈随易1 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
云-缩影3 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
Dream-Y.ocean4 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
考虑考虑4 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
Csvn5 小时前
性能监控
前端
Highcharts.js5 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
无奈何杨5 小时前
风控决策系统决策流,策略模式,权重、顺序、投票、最坏
后端
Csvn5 小时前
构建工具
前端
FRing035 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Patrick_Wilson6 小时前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言