我正在为一个项目开发一个命令行工具集。最后一个工具将支持许多子命令,如下所示
foo command1 [--option1 [value]?]*所以可以有如下的子命令
foo create --option1 value --
foo make file1 --option2 --option3该工具使用and解析库来处理命令行参数和帮助功能等。
一些额外的要求和制约因素:
为了调试和为最小可行的版本进行自我包含的功能,我想开发一些自包含脚本和模块的子命令,如
make.py可以导入到主foo.py脚本中,并在以后作为两个脚本调用
make.py --option1 value etc.和
foo.py make --option1 value现在,我的问题是:如何以最小的冗余来模块化这样一个复杂的CLI工具(例如,参数定义和解析应该只在一个组件中进行编码)?
选项1:将所有内容放入一个大脚本中,但这将变得很难管理。
选项2:为单个模块/文件(如make.py、add.py)中的子命令开发功能;但这种功能必须保持可调用性(通过if __name__ == '__main__' ...)。
然后,可以将来自子命令模块的函数导入主脚本,解析器和子命令中的参数作为子解析器添加。
选项3:主脚本可以简单地将对子命令的调用格式化为子进程,如下所示
subprocess.run('./make.py {arguments}', shell=True, check=True, text=True)发布于 2021-10-03 00:53:22
发布于 2021-10-01 22:23:20
我更习惯于回答有关numpy和argparse细节的问题,但下面是我如何设想一个大型包的方法。
在main.py中
import submod1
# ....
sublist = [submod1, ...]
def make_parser(sublist):
parser = argparse.ArgumentParser()
# parser.add_argument('-f','--foo') # main specific
# I'd avoid positionals
sp = parser.add_subparsers(dest='cmd', etc)
splist=[]
for md in sublist:
sp1 = sp.add_parser(help='', parents=[md.parser])
sp1.set_default(func=md.func) # subparser func as shown in docs
splist.append(sp1)
return parser如果名称为 == 'main':=make_parser(子列表) args = parser.parse_args() # print(args) #调试显示args.func(args) #。
在submod1.py中
导入argparse make_parser():解析器= argparse.ArgumentParser(add_help=False) #检查文档?Parser.add_argument(.)#可以在这里添加一个常见的父级返回解析器
parser.make_parser()
def func(args):
# module specific 'main'我确信这在很多方面是不完整的,因为我是在未经测试的情况下编写的。这是一个基本的子解析器定义,如文档所示,但使用parents导入子模块中定义的子解析器。parents也可以用于为子解析器定义公共参数;但是实用程序函数也同样有效。我认为parents在使用您无法访问的解析器时最有用;即。进口的。
parents实际上是通过引用(而不是值或副本)将操作从一个解析器复制到新的一个副本。这不是一个高度发达的工具,也有很多这样的工具,人们在那里遇到了问题。所以,不要试图过度扩展它。
发布于 2021-10-01 20:06:56
简而言之,创建一个名为Command的抽象类,并使每个命令从Command继承它自己的类。
示例:
class Command():
def execute(self):
raise NotImplementedError()
class Command1(Command):
def __init__(self, *args):
pass
def execute(self):
pass
class Command2(Command):
def __init__(self, *args):
pass
def execute(self):
pass这将处理命令的执行。建造一个指挥工厂。
class CommandFactory():
@staticmethod
def create(command, *args):
if command == 'command1':
return Command1(args)
elif command == 'command2':
return Command2(args)然后,您就可以使用一行执行命令:
CommandFactory.create(command, args).execute()https://stackoverflow.com/questions/69411257
复制相似问题