如何解决Argparse + cmd2 RecursionError即使在简单程序上
示例代码:
package com.missingVariable.Application;
import java.util.Random;
import java.util.concurrent.TimeUnit;
class Bot { // I created a class
public final int originalSN = 0; // Original serial number to be searched
private final int rangeSerialNumber = 1000;
private Random SN = new Random(); // Serial number randomizer
// Bot serial number
private int botSerialNumber = SN.nextInt(rangeSerialNumber); // Sets the bot's serial number
public int getSN() { // A getter for the bot's serial number
return this.botSerialNumber;
}
// Bot parent number
private int parentSerialNumber = SN.nextInt(rangeSerialNumber); // Sets the bot's parent number
public int getParentSN() { // A getter for the bot's serial number
return this.parentSerialNumber;
}
public void setNewBotSN(int botSerialNumber) {
this.botSerialNumber = botSerialNumber;
}
// Bot constructor
public Bot() {
System.out.println("Bot serial number " + getSN());
System.out.println("Bot parent number " + getParentSN());
System.out.println();
}
}
public class Application {
public static void main(String[] args) throws InterruptedException {
int botCounter = 0;
int botPopulation = 1000;
// Loop
while (botCounter < botPopulation) {
TimeUnit.SECONDS.sleep(1); // Delay
Bot bot = new Bot(); // Creates new bot
if (bot.getSN() == bot.originalSN) { // Main Code
System.out.println("Bot found!");
break;
} else {
System.out.println("Current bot serial number does not match");
bot.setNewBotSN(bot.getParentSN()); // Changes the the serial number to parent number
System.out.println("New bot serial number is " + bot.getSN());
System.out.println();
botCounter++;
}
}
}
}
在示例中,我试图制作一个可以在单一模式(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()
)或cmd /提示模式(program.py single -sp test
)下运行的程序,然后将其称为单一模式或其他操作(在外壳内部,编写program.py cmd
或single -sp test
。无论如何,如果我尝试获取cmd2类中do_single中使用的argparse的所有值,我将得到other
使用cmd2的调试,它可以完成:
EXCEPTION of type 'RecursionError' occurred with message: 'maximum recursion depth exceeded in comparison'
我使用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",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
函数的原因是因为我正在创建要由cmd2.Cmd子类使用的子解析器,但是当从主调用时,我想对模式使用相同的解析器贝壳。这基本上是一个最低限度的工作示例,我的代码有很多标志和其他内容。
另一方面,该问题似乎是由于create_subparser
而引起的。似乎它尝试执行print(opts)
,并且在尝试枚举所有变量时,由于某处的递归而耗尽了内存。如果我不尝试列出对象内的所有变量(例如,如果我仅使用vars(opts)
),它将起作用。这似乎与我试图在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))
136 else:
137 star_args[name] = value
RecursionError: maximum recursion depth exceeded while calling a Python object
您可以测试各个属性,直到找到问题所在:
In [432]: list(ns.__dict__.keys())
Out[432]: ['foo','baz','ns']
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。