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, 拼命令, 处理流, 解析输出, 一通操作猛如虎。

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

相关推荐
赖龙4 小时前
pnpm vs npm
前端·npm·node.js
To_OC4 小时前
LC 239 滑动窗口最大值:从暴力超时到单调队列一遍过
javascript·算法·leetcode
To_OC4 小时前
从一行入口代码啃透 NestJS:工厂模式、装饰器和依赖注入是怎么串起来的
后端·设计模式·nestjs
Python私教4 小时前
多个项目怎么安全合并?先适配,再切换
后端·python·架构
学如逆水,不进则退5 小时前
在线免费音频剪辑:NBTools 可视化波形裁剪 MP3/WAV,本地处理免上传
前端·音视频
Mh5 小时前
虚拟滚动真的比普通滚动性能更好吗?
前端·javascript·性能优化
pe7er5 小时前
React + Ant Design 中的 IME (输入法合成)安全输入组件
前端
Python私教6 小时前
从表格到管理系统:别先写页面,先补齐权限、流程和审计
数据库·后端·架构
Super 含6 小时前
Android 启动优化(二):TTID、TTFD 与 Macrobenchmark 启动性能测量
前端
Python私教6 小时前
别急着加 llms.txt:企业官网面向 AI 搜索的工程清单
前端·人工智能·seo