普贤教程 › 生态包
文件系统
文件系统这一组:glob 通配、shutil 拷贝移动、walk 遍历、fsnotify 变更监听、tempfile 临时文件、dirs 标准目录。
通配与列举
px
import glob print(glob_match("*.px", "gen.px")) # true print(glob_match("src/**/*.px", "src/a/b.px")) # true print(glob_list("/data/work/px-tutorial-20261105/gen", "*.px")) # Ok([/data/work/px-tutorial-20261105/gen/gen.px])
glob_list 返回 Ok(路径列表),不是裸 list;目录不存在返回 Err。写清理脚本时先判 is_err(),别把「目录不存在」当成「没有文件」——后者会让你以为已经干净了。文件操作
px
import shutil sh_mkdirs("/tmp/demo/a/b") sh_write_text("/tmp/demo/a/x.txt", "hello") print(sh_read_text("/tmp/demo/a/x.txt")) # hello sh_copy("/tmp/demo/a/x.txt", "/tmp/demo/a/y.txt") sh_move("/tmp/demo/a/y.txt", "/tmp/demo/z.txt") print(sh_list_files("/tmp/demo/a")) # [x.txt] sh_remove_tree("/tmp/demo")
sh_remove_tree 是递归删除脚本里对路径参数做任何拼接前,先确认它不是空串、不含 ..、不在 / 或家目录上。删除类操作在服务端一律先 print 出「将要删的绝对路径」再做。标准目录
px
import dirs print(dr_home()) # /root print(dr_config()) # /root/.config print(dr_data()) # /root/.local/share print(dr_cache()) # /root/.cache print(dr_app_data("demo")) # /root/.local/share/demo print(dr_pjoin(["a", "b"])) # a/b
遵循 XDG 规范:配置、数据、缓存分开放。部署脚本里别再硬编码 /root/.xxx —— 换用户或换系统就坏。
遍历
px
import walk walk_dir("/data/www", def(path, is_dir): if not is_dir and ends_with(path, ".html"): print(path) )
回调式遍历,不一次性把整棵树读进内存。大目录(几万文件)用它,别用 glob_list 拼 **。
变更监听
px
import fsnotify var w = fs_watch_new("/etc/nginx", "*.conf", 5) # 5 秒轮询间隔 loop: var ch = fs_watch_poll(w) for p in ch: print("changed: " + p) sleep_ms(1000)
它是轮询快照,不是 inotify机制是「定期 stat 比对」,所以:① 有最长一个轮询间隔的延迟;② 文件多时开销随文件数增长;③ 进程重启期间的变更会漏掉(重启要重建基线)。要零延迟用
inotify(系统工具),要「配置改了自动 reload」这种场景它正好够。临时文件
px
import tempfile var d = tf_tempdir("px-") # 建临时目录 var f = tf_tempname_ext(".json") # 只要名字 tf_write(f, "{}") tf_cleanup(d) # 清理
临时文件写在 $TMPDIR(默认 /tmp)。注意 /tmp 常被 tmpfs 或定期清理:跨重启要保留的东西别放这里。
文件操作的纪律
- 先判存在再读:
exists(p)或read_file_opt;read_file遇到不存在会抛错。 - 写文件用
write_file,二进制用write_bytes:write_file对 bytes 会写成<bytes N>字符串。 - 大文件分块:
write_all一次写超过 16 MiB 会挂死(实测)。 - 路径拼接用
dr_pjoin,别手拼/——尾部斜杠重复会变成//,某些场景下语义不同。