Snakemake运行时传递logger.get_logfile()路径至脚本返回None的问题
问题描述
我尝试在工作流仍在运行时使用全局工作流日志文件,相关代码示例如下:
workflow.smk
from snakemake.logging import logger path_to_log=logger.get_logfile() rule all: input: "some_file.txt" rule test: output: "some_file.txt" params: path_to_log=path_to_log script: "tracking_memory_usage.py"
tracking_memory_usage.py
with open(snakemake.params.path_to_log) as log_file: #do_stuff
执行命令:
snakemake -s testing_memory_tracking.smk --cores 2 --profile slurm/ --configfile config_file.yaml
我在规则外部打印path_to_log能得到预期的当前运行工作流的日志路径,但把该变量传递给params后,在脚本中访问时返回值为None。我甚至尝试复制变量值再传递,结果还是一样:
from snakemake.logging import logger import copy path_to_log=logger.get_logfile() copy_of_path=copy.copy(path_to_log) rule all: input: "some_file.txt" rule test: output: "some_file.txt" params: path_to_log=copy_of_path script: "tracking_memory_usage.py"
使用的Snakemake版本为v7.18.2,请问为什么会出现这种情况?
原因及解决办法
原因
Snakemake的执行分为解析阶段和运行阶段:
- 解析阶段:Snakefile被加载,所有顶层代码(包括
logger.get_logfile())会被执行,但此时工作流的日志文件还未完全初始化——尤其是使用Slurm集群配置时,日志路径要到运行阶段才会最终确定。 - 规则的
params在解析阶段就会被固化存储,当后续进入运行阶段执行脚本时,之前解析阶段获取的path_to_log已经失效,最终变为None。
解决办法
有两种可行的修复方式:
方式1:在脚本内部动态获取日志路径
直接在tracking_memory_usage.py中调用logger.get_logfile(),确保在脚本运行时(工作流已启动,日志路径已确定)获取有效路径:
from snakemake.logging import logger path_to_log = logger.get_logfile() with open(path_to_log) as log_file: # 执行你的操作
方式2:用lambda延迟获取路径
如果必须在Snakefile的params中传递路径,使用lambda函数延迟logger.get_logfile()的执行时机,让它在规则运行时才被调用:
from snakemake.logging import logger rule all: input: "some_file.txt" rule test: output: "some_file.txt" params: path_to_log=lambda wildcards: logger.get_logfile() script: "tracking_memory_usage.py"
这样就能保证传递给脚本的是有效的日志路径,不会出现None的情况。
内容的提问来源于stack exchange,提问作者ABS
相关产品推荐
相关产品推荐

