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 这头会抛 ShellErrorexitCode 是退出码, 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, 拼命令, 处理流, 解析输出, 一通操作猛如虎。

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

相关推荐
hunterandroid2 小时前
Service 与前台服务:让任务在后台持续运行
前端
米饭同学i2 小时前
深扒 LobsterAI 官网前端动效实现方案:从交互细节到代码实践
前端
菜鸟谢2 小时前
Rust 枚举 (enum) 完整核心知识点
后端
前端啊2 小时前
告别 el-table 打印难题,vue3-print-el-table 来了!
前端·vue.js
JarvanMo2 小时前
AI时代跨平台还有必要吗?
前端
晓杰在写后端2 小时前
从0到1实现Balatro游戏后端(9):Blind奖励结算与金币系统实现
后端·游戏开发
Patrick_Wilson2 小时前
幂等到底是什么?从前端视角讲透 SQL、HTTP 与 POST 接口的幂等设计
前端·后端·架构
凌览2 小时前
一人公司别再上 Jenkins,真不值
前端·后端
菜鸟谢2 小时前
Rust 元组与数组内存管理笔记
后端