【发布时间】:2018-11-04 01:20:47
【问题描述】:
我想制作一个可以被命令行和其他模块使用的 Python 模块。 像这样:
python3 Capacity.py arg1 arg2 arg3
or
>>> capacity.execByString("arg1 arg2 arg3")
我做了一个类(通过一些研究)在代码中获取 argparse 的结果:
class ArgumentParserError(Exception): pass
class Parseur(ArgumentParser):
def error(self, msg):
raise ArgumentParserError(msg)
def analyze(self, args):
if type(args) is not list:
args = args.split() # To work with a String
try:
result = self.parse_args(args)
return True, result
# Returns True and the namespace if OK
except ArgumentParserError as err:
return False, err.args[0]
# Returns False and the error message if not OK
我是这样使用它的:
class Capacity():
def __init__(self):
self.parser = Parseur()
# Config the parser
def execByArguments(*args):
# Do the job
def execByString(command):
isOK, result = self.parser.analyze(command)
if isOk:
# Launch execByArguments with the rights args in result
else:
# Print error message
print(result)
def execFromCommandLine():
args = self.parser.parse_args()
# Launch execByArguments with the rights args
if __name__ == "__main__":
execFromCommandLine()
但是有两个主要问题,当然还有一些我还没有发现:
- args 解析不正确(例如双引号),因为 split 函数具有“空格”分隔符
- 仍然使用 -h 标志关闭程序
我确信将其作为另一个 Parseur 类是无用的/不好的,并且有一种解决方法。 通过子进程启动模块也不是一个好主意:在这种情况下,我想获取返回的对象。 你能帮我找到一个很酷的方法来做我想做的事吗? 已经谢谢了。
PS:在网上写代码好痛苦^^。
【问题讨论】:
-
我很好奇:您出于什么原因要支持
capacity.execByString("arg1 arg2 arg3")而不是capacity.execByString("arg1", "arg2", "arg3")或capacity.execByString(["arg1", "arg2", "arg3"])? -
shlex.split像壳一样拆分字符串。默认情况下,-h操作会显示帮助并执行sys.exit。如果您不想退出,则需要在if/except块中捕获它,或者使用add_help=False参数省略它。然后,您可以将自己的-h添加为store_true。 -
事实上,我从 Telegram(一个 msg 应用程序)中获取字符串,我只想使用消息内容调用正确的容量,并使用容量类子类的多态性。 argparse 模块非常有用,我需要使用它。然后,直接从命令行调用模块只是奖励! ^^
-
@hpaulj 哦!那很有用!我现在要测试它..
-
@lial_slasher 嵌入是什么意思?你可以做
arg_parser.parse(shlex.split(input_string))