px普贤教程PuXian
普贤教程 › 基础教程

模块与导入

PuXian 的模块系统只有一件事:把别的文件里的函数变成当前文件可用的函数。没有命名空间前缀,没有 package 声明。

三种 import

px
import "lib.px"        # 同目录的源文件
import std.strings     # 标准库模块
import mysql           # 生态包(registry,需先 pxpkg install)
写法来源说明
import "x.px"项目内文件相对当前文件的路径,引号不能省
import std.xxxstdlib/27 个标准库模块
import 包名registry/ 或 .px_modules/裸名字,需要项目里装过

项目内拆分文件

把公共函数放进一个文件,其他文件 import 它:

px
# lib/mathutil.px
def clamp(x, lo, hi):
    if x < lo:
        return lo
    if x > hi:
        return hi
    return x

def pct(a, b):
    if b == 0:
        return 0.0
    return a / b * 100
px
# app.px
import "lib/mathutil.px"

print(str(clamp(120, 0, 100)))
print(str(pct(3, 4)))
text
100
75.0

import 之后,被导入文件的函数直接进入当前作用域——不需要 mathutil.clamp() 这样的前缀。代价是命名要自己管好,别在两个文件里定义同名函数。

标准库

px
import std.strings

print(str(index_of("中文ab", "b")))
print(str(last_index_of("a.b.c", ".")))
text
3
3

标准库模块清单见 标准库概览。lib 内部互相 import 时用的是文件相对路径;你只需要 import 顶层那个模块。

生态包(registry)

registry 里有 195 个包。项目里装依赖的标准流程:

sh
pxpkg init --name myapp          # 生成 px.toml
pxpkg add mysql@0.2.0            # 写进依赖
pxpkg install                    # 落地到 .px_modules/
pxpkg list                       # 看装了哪些
px
import mysql
解析顺序裸名 import 会先找项目里的 .px_modules/,再找 PX_REGISTRY 指向的 registry 目录。没有 pxpkg install 就直接 import,会得到「找不到模块」。

import 的路径规则

  • import "x.px" 是相对当前文件的路径;子目录写成 import "lib/x.px"。
  • import std.xxx 会依次尝试 ./stdlib、../stdlib、PX_STDLIB。
  • 在解压目录之外跑 px,标准库要靠 PX_STDLIB 环境变量指过去。
不要跨目录 importimport "../other/lib.px" 在本地能跑,但把它部署到 Ma 的 px_routes 时会失败:Ma 编译时只把「脚本所在目录」打包成沙箱,跨目录的目标不在里面,编译只能跳过该 import,运行期报「未定义变量」。
正确做法是把公共库复制一份进本目录,用同目录相对路径引用。

循环依赖

两个文件互相 import 时行为不保证。把公共部分抽到第三个文件,两边都 import 它——这也顺便让依赖方向变成单向。

模块里的顶层代码

被 import 的文件如果有顶层 print,第一次 import 时会执行一次。所以库文件里只放函数与常量声明,不要放有副作用的语句:

px
# ❌ 库文件里不要这样
print("lib 被加载了")

# ✅ 只声明
def helper():
    return 1

组织建议

规模建议结构
单文件脚本一个 .px,不拆
小工具(3–5 个文件)同目录:main.px + lib.px + 各自模块
服务(10+ 文件)按职责分目录,每个目录内自包含,公共库复制或显式同步
公共库要能独立测试把纯函数(无 IO、无网络)集中在 lib.px,配一个 t_lib.px 断言脚本;这样改公共库时能一分钟内回归。