Python Argparse+;cmd2递归错误,即使在简单程序上也是如此
示例代码:Python Argparse+;cmd2递归错误,即使在简单程序上也是如此,python,python-3.x,recursion,argparse,cmd2,Python,Python 3.x,Recursion,Argparse,Cmd2,示例代码: import argparse import cmd2 import sys def create_subparser(a_parser = None): if a_parser is None: new_parser = argparse.ArgumentParser() else: new_parser = a_parser.add_parser("single") new_parser.add_ar
import argparse
import cmd2
import sys
def create_subparser(a_parser = None):
if a_parser is None:
new_parser = argparse.ArgumentParser()
else:
new_parser = a_parser.add_parser("single")
new_parser.add_argument("--single-param", "-sp")
return new_parser
def single_print(some_param):
print("single operation " + str(some_param))
def other_print():
print("other operation")
class TestCmd(cmd2.Cmd):
single_parser = create_subparser()
@cmd2.with_argparser(single_parser)
def do_single(self, opts):
print(opts)
single_print(opts.single_param)
def do_other(self, opts):
other_print()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help="commands", dest="mode")
create_subparser(subparsers)
cmd_parser = subparsers.add_parser("cmd", help="shell")
args = parser.parse_args()
if args.mode == "single":
single_print(args.single_param)
else:
sys.argv = [sys.argv[0]] # cmd2 complains about unknown parameters without
cmd = TestCmd()
cmd.cmdloop()
在本例中,我试图创建一个程序,该程序可以在单一模式(program.py single-sp test
)或cmd/prompt模式(program.py cmd
)下运行,然后调用单一模式或其他操作(在shell中,编写single-sp test
或other
。无论如何,如果我尝试获取cmd2类中do_single中使用的argparse的所有值,我会得到类型为“RecursionError”的异常,并显示消息:“比较中超过了最大递归深度”
。使用cmd2的调试,它会:
Traceback (most recent call last):
File "/home/.../site-packages/cmd2/cmd2.py", line 2011, in onecmd_plus_hooks
stop = self.onecmd(statement, add_to_history=add_to_history)
File "/home/.../site-packages/cmd2/cmd2.py", line 2441, in onecmd
stop = func(statement)
File "/home/.../site-packages/cmd2/decorators.py", line 308, in cmd_wrapper
return func(*args_list, **kwargs)
File "test.py", line 28, in do_single
print(opts)
File "/usr/lib/python3.7/argparse.py", line 131, in __repr__
arg_strings.append('%s=%r' % (name, value))
File "/usr/lib/python3.7/argparse.py", line 131, in __repr__
arg_strings.append('%s=%r' % (name, value))
File "/usr/lib/python3.7/argparse.py", line 131, in __repr__
arg_strings.append('%s=%r' % (name, value))
[Previous line repeated 326 more times]
File "/usr/lib/python3.7/argparse.py", line 129, in __repr__
for name, value in self._get_kwargs():
File "/usr/lib/python3.7/argparse.py", line 139, in _get_kwargs
return sorted(self.__dict__.items())
RecursionError: maximum recursion depth exceeded in comparison
我之所以使用create_subparser
函数,是因为我正在创建cmd2.Cmd子类要使用的子parser,但是我想在从主shell调用时对模式使用相同的解析器。这基本上是一个最小的工作示例,我的代码有更多的标志等等
还有一件事,这个问题似乎是因为
print(opts)
而发生的。它似乎试图执行vars(opts)
并且当它尝试枚举所有变量时,由于某个地方的递归而耗尽内存。如果我不尝试列出对象中的所有变量(例如,如果我只使用了opts.single_param
),它会起作用。这似乎与我试图在cmd2内部和主程序中使用相同的argparser有关,但我不明白它发生的确切原因以及它是否可以修复。如果没有cmd2
,我无法运行您的代码。但我可以创建一个显示您问题的命名空间
In [429]: ns = argparse.Namespace(foo='bar', baz=12)
In [430]: ns.ns = ns
In [431]: print(ns)
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-431-0769451eb86e> in <module>
----> 1 print(ns)
/usr/lib/python3.6/argparse.py in __repr__(self)
133 for name, value in self._get_kwargs():
134 if name.isidentifier():
--> 135 arg_strings.append('%s=%r' % (name, value))
136 else:
137 star_args[name] = value
... last 1 frames repeated, from the frame below ...
/usr/lib/python3.6/argparse.py in __repr__(self)
133 for name, value in self._get_kwargs():
134 if name.isidentifier():
--> 135 arg_strings.append('%s=%r' % (name, value))
136 else:
137 star_args[name] = value
RecursionError: maximum recursion depth exceeded while calling a Python object
没有
cmd2
我无法运行您的代码。但我可以创建一个显示您的问题的命名空间
In [429]: ns = argparse.Namespace(foo='bar', baz=12)
In [430]: ns.ns = ns
In [431]: print(ns)
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-431-0769451eb86e> in <module>
----> 1 print(ns)
/usr/lib/python3.6/argparse.py in __repr__(self)
133 for name, value in self._get_kwargs():
134 if name.isidentifier():
--> 135 arg_strings.append('%s=%r' % (name, value))
136 else:
137 star_args[name] = value
... last 1 frames repeated, from the frame below ...
/usr/lib/python3.6/argparse.py in __repr__(self)
133 for name, value in self._get_kwargs():
134 if name.isidentifier():
--> 135 arg_strings.append('%s=%r' % (name, value))
136 else:
137 star_args[name] = value
RecursionError: maximum recursion depth exceeded while calling a Python object
必须阅读并遵循您的代码。它看起来确实像是一个递归定义的
命名空间
对象,但我不知道它是如何产生的。我想知道print(vars(opts))
是否工作得更好。(vars(opts))
似乎首先导致了这个问题。我相信一旦我尝试打印,就会在方法中调用它将其转换为字符串。因此它没有任何不同。必须阅读并遵循您的代码。它看起来确实像是一个递归定义的命名空间
对象,但我不知道它是如何生成的。我想知道打印(vars(opts))
工作得更好。(vars(opts))
似乎首先导致了这个问题。我相信在我尝试打印后,在方法中会调用它来转换为字符串。所以这没有什么不同。