Python改argv对命令行语句Debug(2025/08/18更新)

2025/08/18更新:添加对另一种传参的适配方法。
前言
- 开源代码通常放命令行的运行形式,例如
python train.py --dataset cifar10
,但命令行执行无法debug。 - 我以前的做法是改main函数,令其能够单独接收参数,例如
def main(dataset, lr, epoch)
,然后再用一个额外的startup.py文件来运行这个main函数,以在传参的时候进行debug。- 它的好处是startup.py里可以复制多行执行语句,来一次性顺序执行多个实验,例如
main("cifar10"); main("voc")
- 缺点是不同代码的传参形式不一样,所以有的改起来麻烦
- 它的好处是startup.py里可以复制多行执行语句,来一次性顺序执行多个实验,例如
- 还有一种做法是不改main的传参,而是生成配置文件,例如
config.yaml
,- 和改main函数一样,但更简单
- 缺点是并行实验得小心,如果两个实验同时进行,同时修改一个配置文件,会导致一个实验被并行的重复执行。
- 现在我找到了一个更简单的方案,看起来也很通用,即修改
sys.argv
- 目前看来上面的缺陷都被很好的避免了。
方法1
- 注:这个适用于
Hydra
,argparse.ArgumentParser()
见方法2 - 创建一个startup.py文件,
- 定义一个
run(arg1, arg2, arg3)
函数,- 在函数内,用
sys.argv=["startup.py", f"arg1={arg1}", f"arg2={arg2}", f"arg3={arg3}"]
来准备参数 - 随后执行train.py里的
main()
函数
- 在函数内,用
- 在
if __name__ == "__main__":
里,用run(arg1, arg2, arg3)
来传参并执行
示例1
- 这份代码用于执行mm-graph-benchmark的节点分类实验。
from main import main
import os
import sys
import datetime
config = {
"ele-fashion":{
"MMGCN": {
"clip": {
"lr": 0.01617331603,
"num_layers": 1
},
"t5vit": {
"lr": 0.0001215688562,
"num_layers": 2
}
}
}
}
def run(
ID = 0,
dataset = "ele-fashion",
model = "SAGE",
feat = "clip",
n_epochs = 30,
runs = 3
):
time_now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
sys.argv = [
"startup.py",
f"hydra.run.dir=nc/logs/{ID}/{model}-{feat}/{time_now}/",
f"model_name={model}",
f"dataset={dataset}",
f"feat={feat}",
f"lr={config[dataset][model][feat]['lr']}",
f"num_layers={config[dataset][model][feat]['num_layers']}",
f"n_epochs={n_epochs}",
f"runs={runs}"
]
main()
if __name__ == "__main__":
ID = "b1"
""" 74.35±0.01 """
# run(ID, dataset="books-nc", model="GCN", feat="clip")
""" 76.33±0.04 """
# run(ID, dataset="books-nc", model="GCN", feat="t5vit")
""" 72.99±0.16 """
# run(ID, dataset="books-nc", model="GCN", feat="imagebind")
""" 81.78±0.02 """
# run(ID, dataset="books-nc", model="GCN", feat="t5dino")
方法2
- 与方法1类似,但是传参改为
sys.argv=["startup.py", "--arg1", arg1, "--arg2", arg2, "--arg3", arg3]
示例2
from pathlib import Path
from train import main
import os
import sys
datasets_info = {
"RSICD": {
"train_json": "G:/1_Data/Datasets/RSICD/dataset_rsicd.json",
"train_img": "G:/1_Data/Datasets/RSICD/RSICD_images/",
},
"RSITMD": {
"train_json": "G:/1_Data/Datasets/RSITMD/dataset_RSITMD.json",
"train_img": "G:/1_Data/Datasets/RSITMD/images/",
},
}
def run(
ID = 0,
dataset = "RSITMD",
gpu = 3,
w1 = 0.0,
start_epoch = 0
):
log_dir = f"{Path(__file__).parent.resolve()}/logs/{ID}/{dataset}/w_{w1}-stE_{start_epoch}/"
os.environ["CUDA_VISIBLE_DEVICES"] = f"{gpu}"
sys.argv = [
"startup.py",
f"--train_result", log_dir,
f"--train_json", datasets_info[dataset]['train_json'],
f"--train_img", datasets_info[dataset]['train_img'],
f"--w1", w1,
f"--start_epoch", start_epoch
]
main()
if __name__ == "__main__":
ID = "Baseline"
gpu = 0
run(ID=ID, dataset="RSITMD", gpu=gpu)
run(ID=ID, dataset="RSICD", gpu=gpu)
run(ID=ID, dataset="RSTPReid", gpu=gpu)
共有 0 条评论