
cookiecutter 本身不支持在 `cookiecutter.json` 中直接执行函数,但可通过预处理脚本动态注入运行时生成的选项(如本地已安装的程序列表),再启动交互式模板渲染。
在数据科学项目模板中,常需将外部依赖(如 Python、R、CUDA 或特定 CLI 工具)的版本与项目生命周期对齐。由于这些工具版本因开发环境而异,且项目部署周期较短(数月)、环境固定,硬编码版本虽不可移植,却具备合理性和可维护性——但前提是该“硬编码值”能自动适配当前系统。
cookiecutter.json 是纯静态 JSON 文件,不支持表达式、函数调用或变量插值。因此,类似 "program_version": ["generate_program_choices()"] 的写法无效,会被原样当作字符串处理。
✅ 正确做法:使用预生成脚本(pre-generation hook) 动态更新配置文件:
传媒企业网站系统使用热腾CMS(RTCMS),根据网站板块定制的栏目,如果修改栏目,需要修改模板相应的标签。站点内容均可在后台网站基本设置中添加。全站可生成HTML,安装默认动态浏览。并可以独立设置SEO标题、关键字、描述信息。源码包中带有少量测试数据,安装时可选择演示安装或全新安装。如果全新安装,后台内容充实后,首页才能完全显示出来。(全新安装后可以删除演示数据用到的图片,目录在https://
-
编写 generate_program_choices.py(示例):
# generate_program_choices.py import subprocess import json
def get_installed_python_versions(): try:
示例:获取系统中所有可用的 python3.x 版本
result = subprocess.run(
["bash", "-c", "ls /usr/bin/python3.* 2>/dev/null | xargs -n1 basename | sort -V"],
capture_output=True, text=True, check=True
)
versions = [v.strip() for v in result.stdout.strip().splitlines() if v.strip()]
return versions or ["python3.9", "python3.10", "python3.11"]
except Exception:
return ["python3.10"]if name == "main": print(json.dumps(get_installed_python_versions(), indent=2))
2. **创建 `update_choices.py` 预处理脚本**(放在模板根目录):
```python
# update_choices.py
import json
import sys
from pathlib import Path
# 假设 generate_program_choices 是一个模块或可导入函数
# 若为独立脚本,建议改用 subprocess 调用并解析 stdout(更健壮)
sys.path.insert(0, str(Path(__file__).parent))
from generate_program_choices import get_installed_python_versions
# 读取并更新 cookiecutter.json
config_path = Path("cookiecutter.json")
with config_path.open("r", encoding="utf-8") as f:
config = json.load(f)
config["program_version"] = get_installed_python_versions()
with config_path.open("w", encoding="utf-8") as f:
json.dump(config, f, indent=4, ensure_ascii=False)
print(f"✓ Updated program_version choices in {config_path.name}")-
执行流程(终端命令):
python update_choices.py cookiecutter .
⚠️ 注意事项:
- 确保 generate_program_choices() 执行快速、无副作用(不修改系统状态);
- 若模板需跨平台,函数内应做 OS 判断(如 platform.system());
- 避免在 cookiecutter.json 中保留占位符字段(如 "program_version": []),否则可能触发 Cookiecutter 的空列表校验警告;推荐初始设为合理默认值(如 ["python3.10"]);
- 如需更高自动化,可将上述两步封装为 Makefile 或 pre_gen_project.sh(需启用 Cookiecutter 的 hooks 机制,但注意:pre_gen_project hook 运行于用户输入前,无法读取 cookiecutter.json 中的 prompt 值,故仍推荐显式预处理 JSON 文件)。
总结:动态选项的本质是「配置即代码」——将环境感知逻辑移出声明式配置,交由 Python 脚本完成元配置生成。这既保持了 cookiecutter.json 的简洁性与兼容性,又赋予模板强大的上下文感知能力,是专业级 Cookiecutter 模板的典型实践模式。









