如何在Python CookieCutter项目中自动更新README.md?
问题分析与解决方案
你的问题核心出在cookiecutter变量的错误取值方式,以及未处理多行折叠的文件夹说明行,同时逻辑判断的写法存在优先级歧义,最终导致所有行被错误跳过。
1. 错误原因拆解
- 模板变量解析失效:你在
post_gen_project.py中用"{{ cookiecutter.include_gui_structure }}" == "false"的模板字符串写法,但CookieCutter执行脚本时,布尔类型变量会被替换为Python布尔值(如False)而非字符串,导致False == "false"比较结果为False,逻辑判断完全偏离预期。 - 多行说明行未处理:像
│ │ predictions这种属于上一行文件夹说明的换行内容,你的脚本未识别并跳过,不仅会导致结构格式混乱,还可能触发错误的全量跳过逻辑。 - 逻辑优先级歧义:虽然AND优先级高于OR,但未给每个条件组加明确括号,可能导致判断逻辑与预期不符。
2. 修复后的post_gen_project.py
import os from cookiecutter.main import cookiecutter PROJECT_DIRECTORY = os.path.realpath(os.path.curdir) def update_readme(): lines = [] gui_indicators = [ "Folder for storing assets like images", "Contains your application views", "Contains all style related code", "Contains custom widgets", ] data_science_indicators = [ "Trained and serialized models, model predictions, or model summaries", "Scripts to turn raw data into features for modeling", "Scripts to train models and then use trained models to make", "Scripts to create visualizations", ] # 直接获取cookiecutter的布尔变量值 use_pre_commits = cookiecutter['use_pre_commits'] use_sphinx = cookiecutter['use_sphinx_documentation'] include_gui = cookiecutter['include_gui_structure'] include_ds = cookiecutter['include_data_science_structure'] # 读取原始README内容 with open(os.path.join(PROJECT_DIRECTORY, "README.md"), "r") as file: lines = file.readlines() skip_line = False keep_lines = [] for line in lines: current_skip = False # 逐个判断需要跳过的行 if not use_pre_commits and "Configuration file for the pre-commits" in line: current_skip = True elif not use_sphinx and "A default Sphinx project; see sphinx-doc.org for details" in line: current_skip = True elif not include_gui and any(indicator in line for indicator in gui_indicators): current_skip = True elif not include_ds and any(indicator in line for indicator in data_science_indicators): current_skip = True # 处理多行续行:如果上一行是跳过状态,当前行是缩进的说明续行则继续跳过 if skip_line: stripped_line = line.strip() if not stripped_line or stripped_line.startswith("│") or stripped_line.startswith("└") or stripped_line.startswith("├"): current_skip = True else: skip_line = False if current_skip: skip_line = True else: keep_lines.append(line) skip_line = False # 写入处理后的内容 with open(os.path.join(PROJECT_DIRECTORY, "README.md"), "w") as file: file.writelines(keep_lines) if __name__ == "__main__": update_readme()
3. 额外注意事项
- 变量类型匹配:你的
cookiecutter.json中变量为布尔类型(如"include_gui_structure": false),脚本中直接用布尔值比较即可,无需转成字符串。 - 测试边界场景:分别测试
include_gui_structure和include_data_science_structure为true/false的组合,验证项目结构是否正确保留或删除。 - 备份原始文件:测试前备份模板中的
README.md,避免误操作导致内容丢失。
内容的提问来源于stack exchange,提问作者JK27
相关产品推荐
相关产品推荐

