You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python脚本生成带动态元数据的复杂项目模板文件

最优解决方案:使用模板引擎

这是目前项目脚手架工具的通用实现方案,同时解决了你提到的两种思路的缺陷:既可以将模板文件独立存放、单独维护,又支持动态变量、甚至复杂逻辑的填充,完全适配多文件、大体积模板的场景。

方案1:Python标准库 string.Template(无第三方依赖,适合简单场景)

不需要额外安装依赖,足以覆盖大多数基础模板生成需求:

  • 第一步:在你的预存模板文件中,将需要动态替换的元数据用$变量名格式占位即可,示例setup.py模板内容:
from setuptools import setup, find_packages

setup(
    name="$project_name",
    version="$version",
    packages=find_packages(),
    install_requires=$dependencies,
    license="$license_type",
    description="$description"
)
  • 第二步:读取模板、替换变量后写入目标路径,代码示例:
import os
from string import Template
from shutil import copy

# 预存模板的文件夹路径
TEMPLATE_DIR = "./py_project_templates"
# 用户传入的动态元数据
context = {
    "project_name": "helloworld",
    "version": "0.1.0",
    "dependencies": ["requests>=2.28.0", "loguru>=0.7.0"],
    "license_type": "MIT",
    "description": "这是一个示例项目"
}
# 生成项目的目标路径
TARGET_DIR = "./generated_project"

# 遍历模板文件夹所有文件
for root, _, files in os.walk(TEMPLATE_DIR):
    # 计算目标目录的相对路径,保持目录结构一致
    rel_path = os.path.relpath(root, TEMPLATE_DIR)
    target_root = os.path.join(TARGET_DIR, rel_path)
    os.makedirs(target_root, exist_ok=True)
    
    for file_name in files:
        src_path = os.path.join(root, file_name)
        dst_path = os.path.join(target_root, file_name)
        
        # 二进制文件(比如图片、字体等)不需要渲染,直接复制
        if file_name.endswith((".png", ".jpg", ".ico")):
            copy(src_path, dst_path)
            continue
        
        # 文本文件走模板替换逻辑
        with open(src_path, "r", encoding="utf-8") as f:
            template = Template(f.read())
        with open(dst_path, "w", encoding="utf-8") as f:
            f.write(template.substitute(context))

注:如果模板中需要保留原义的$字符,写$$即可完成转义。

方案2:Jinja2模板引擎(适合复杂模板场景)

如果你的模板需要支持条件判断、循环、过滤器等复杂逻辑(比如根据用户选择是否生成Dockerfile、动态生成依赖列表),可以使用Python生态通用的Jinja2模板引擎:

  • 安装依赖:
pip install jinja2
  • 模板文件使用Jinja2语法占位,示例requirements.txt模板:
pytest>=7.4.0
{% if use_requests %}
requests>=2.31.0
{% endif %}
{% if use_pydantic %}
pydantic>=2.0.0
{% endif %}

示例setup.py模板:

from setuptools import setup, find_packages

setup(
    name="{{ project_name }}",
    version="{{ version }}",
    packages=find_packages(),
    install_requires=[
        {% for dep in dependencies %}
        "{{ dep }}",
        {% endfor %}
    ],
    {% if license_type == "MIT" %}
    license="MIT",
    classifiers=["License :: OSI Approved :: MIT License"]
    {% endif %}
)
  • 渲染代码示例:
import os
from shutil import copy
from jinja2 import Environment, FileSystemLoader

TEMPLATE_DIR = "./py_project_templates"
env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
context = {
    "project_name": "helloworld",
    "version": "0.1.0",
    "dependencies": ["requests>=2.28.0", "loguru>=0.7.0"],
    "license_type": "MIT",
    "use_requests": True,
    "use_pydantic": False
}
TARGET_DIR = "./generated_project"

for root, _, files in os.walk(TEMPLATE_DIR):
    rel_path = os.path.relpath(root, TEMPLATE_DIR)
    target_root = os.path.join(TARGET_DIR, rel_path)
    os.makedirs(target_root, exist_ok=True)
    
    for file_name in files:
        src_path = os.path.join(root, file_name)
        dst_path = os.path.join(target_root, file_name)
        
        # 二进制文件直接复制
        if file_name.endswith((".png", ".jpg", ".ico")):
            copy(src_path, dst_path)
            continue
        
        template = env.get_template(os.path.join(rel_path, file_name))
        with open(dst_path, "w", encoding="utf-8") as f:
            f.write(template.render(context))

内容的提问来源于stack exchange,提问作者God-status

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:45:00