如何避免argparse默认值与类默认值的冗余定义?
如何避免类默认值与argparse默认值重复定义?
先看我遇到的典型代码结构:
import argparse class A: def __init__(self,val=1): self.val = val if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--val', default=1) args = parser.parse_args() a = A(val=args.val)
这里的问题是:类的构造函数有带默认值的可选参数,但argparse里又要重复定义一遍相同的默认值。后续如果要修改默认值,必须在两处同时修改,很容易出错。
我试过几种思路,但都有缺点:
- 只在类里保留默认值不可行,因为这个类还会在其他地方被直接初始化,不能依赖命令行参数;
- 把argparse的默认值设为None,再判断是否传入类,但变量多了之后代码会变得非常繁琐;
- 目前能想到的是在代码顶部定义
DEFAULT_val这类常量,确保默认值只定义一次,但想知道有没有更优雅的方案?
方案1:通过inspect模块读取类构造函数的默认值
直接从类的__init__方法中提取参数默认值,不需要额外定义常量:
import argparse import inspect class A: def __init__(self, val=1): self.val = val if __name__ == '__main__': # 获取A类构造函数的参数签名 sig = inspect.signature(A.__init__) # 提取val参数的默认值 default_val = sig.parameters['val'].default parser = argparse.ArgumentParser() parser.add_argument('--val', default=default_val) args = parser.parse_args() a = A(val=args.val)
这样默认值只需要在类的__init__中定义一次,argparse直接读取这个值,后续修改只需要改动类里的默认值即可。
方案2:将默认值定义为类属性
把默认值设为类的静态属性,既供类初始化使用,也能让argparse直接引用:
import argparse class A: DEFAULT_VAL = 1 def __init__(self, val=DEFAULT_VAL): self.val = val if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--val', default=A.DEFAULT_VAL) args = parser.parse_args() a = A(val=args.val)
这种方式更直观,不需要依赖第三方模块,其他地方初始化类时,也可以通过A.DEFAULT_VAL来引用默认值,保持全局一致性。
方案3:用dataclass简化定义(Python 3.7+)
如果使用dataclass来定义类,默认值的管理会更简洁,同时可以直接被argparse引用:
import argparse from dataclasses import dataclass @dataclass class A: val: int = 1 if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--val', type=int, default=A.val) args = parser.parse_args() a = A(val=args.val)
dataclass会自动处理字段的默认值,argparse直接引用类的字段默认值,代码结构更清爽。
内容的提问来源于stack exchange,提问作者hasleron
相关产品推荐
相关产品推荐

