背景
根据输入参数给config对象的不同属性赋值
原始实现
import sys
from dataclasses import dataclass
@dataclass
class Config:
aaa: str = None
bbb: str = None
ccc: str = None
ddd: str = None
eee: str = None
def set_config_info(arg: str, value: str = None) -> Config:
config = Config()
if arg == '-a':
config.aaa = value
elif arg == '-b':
config.aaa = value
elif arg == '-c':
config.aaa = value
elif arg == '-d':
config.aaa = value
elif arg == '-e':
config.aaa = value
return config
def set_config_info2(arg: str, value: str = None) -> Config:
"""Python 3.10 """
config = Config()
match arg:
case '-a':
config.aaa = value
case '-b':
config.aaa = value
case '-c':
config.aaa = value
case '-d':
config.aaa = value
case '-e':
config.aaa = value
return config
if __name__ == '__main__':
if len(sys.argv) == 3:
a = sys.argv[1]
v = sys.argv[2]
config_info = set_config_info(a, v)
else:
a = sys.argv[1]
config_info = set_config_info(a)
print('config_info:', config_info)
结果:
PS D:\MyPython\partial> python .\partial.py -a
config_info: Config(aaa=None, bbb=None, ccc=None, ddd=None, eee=None)
PS D:\MyPython\partial> python .\partial.py -a 111
config_info: Config(aaa='111', bbb=None, ccc=None, ddd=None, eee=None)
PS D:\MyPython\partial>
代码点评:if else过多,不好维护和扩展
优化1:应用partial
functools.
partial
(func,* args,**关键字)
返回一个新的部分对象,当被调用时,其行为类似于使用位置参数args 和关键字参数关键字调用的func。如果为调用提供了更多参数,则将它们附加到args。如果提供了其他关键字参数,则它们会扩展和覆盖关键字。
简单说就是把一个函数,和该函数所需传的参数封装到一个class 'functools.partial'的类中,简化以后的调用方式
import sys
from functools import partial
from dataclasses import dataclass
@dataclass
class Config:
aaa: str = None
bbb: str = None
ccc: str = None
ddd: str = None
eee: str = None
def set_value(obj, attr_name, value):
setattr(obj, attr_name, value)
optdict = {
'-a': partial(set_value, attr_name='aaa'),
'-b': partial(set_value, attr_name='bbb'),
'-c': partial(set_value, attr_name='ccc'),
'-d': partial(set_value, attr_name='ddd'),
'-e': partial(set_value, attr_name='eee'),
}
def set_config_info(arg: str, value: str = None) -> Config:
config = Config()
func = optdict.get(arg)
func(config, value=value)
return config
if __name__ == '__main__':
if len(sys.argv) == 3:
a = sys.argv[1]
v = sys.argv[2]
config_info = set_config_info(a, v)
else:
a = sys.argv[1]
config_info = set_config_info(a)
print('config_info:', config_info)
代码点评:if else少了,好维护,易扩展
但是参数读取有点不方便,读取多个参数又该怎么办?有没有更好的办法?
优化2:应用argparse解析工具
argparse 模块是 Python 内置的一个用于命令项选项与参数解析的模块,argparse 模块可以让人轻松编写用户友好的命令行接口。
argparse能够帮助程序员为模型定义参数、通过sys.argv 解析命令行参数。模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。
argparse定义三步骤
(1)创建一个命令行解析器对象——创建 ArgumentParser() 对象
(2)给解析器添加命令行参数 ——调用add_argument() 方法添加参数
(3)解析命令行的参数 ——使用 parse_args() 解析添加的参
代码:
#!/usr/bin/python
from argparse import ArgumentParser
class Config(ArgumentParser):
def __init__(self, description=None):
super().__init__(description=description)
self.add_argument("--aaa", "-a", default=None)
self.add_argument("--bbb", "-b", default=None)
self.add_argument("--ccc", "-c", default=None)
self.add_argument("--ddd", "-d", default=None)
self.add_argument("--eee", "-e", default=None)
if __name__ == '__main__':
config_info = Config(description='config argv')
print('config_info:', config_info.parse_args())
结果:
PS D:\MyPython\partial> python .\partial.py -a 111 -b 222 -c 333 -d 444 -e 555
config_info: Namespace(aaa='111', bbb='222', ccc='333', ddd='444', eee='555')
完结。。。是不是很丝滑,哈哈
参考:
https://www.cnblogs.com/YoungF/p/12047753.html