在ipython中调用parse_args()时出现SystemExit: 2错误。

50

我正在学习Python的基础知识,但在argparse教程的开头就卡住了。 我收到了以下错误:

import argparse
parser = argparse.ArgumentParser()
args = parser.parse_args()
usage: __main__.py [-h] echo
__main__.py: error: unrecognized arguments: -f
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2

%tb命令输出如下:

SystemExit                                Traceback (most recent call last)
<ipython-input-16-843cc484f12f> in <module>()
----> 1 args = parser.parse_args()

C:\Users\Haik\Anaconda2\lib\argparse.pyc in parse_args(self, args, namespace)
   1702         if argv:
   1703             msg = _('unrecognized arguments: %s')
-> 1704             self.error(msg % ' '.join(argv))
   1705         return args
   1706 

C:\Users\Haik\Anaconda2\lib\argparse.pyc in error(self, message)
   2372         """
   2373         self.print_usage(_sys.stderr)
-> 2374         self.exit(2, _('%s: error: %s\n') % (self.prog, message))

C:\Users\Haik\Anaconda2\lib\argparse.pyc in exit(self, status, message)
   2360         if message:
   2361             self._print_message(message, _sys.stderr)
-> 2362         _sys.exit(status)
   2363 
   2364     def error(self, message):

SystemExit: 2

我该如何解决这个问题?


1
你不能在 IPython 中轻松地进行这个实验,因为在 parse_args 中默认使用的是 IPython 命令行。请尝试使用普通的 *.py 文件以及 Python 可执行文件来启动该文件。 - languitar
看看这个argparse。它会对你有所帮助,或者肯定会对其他人有所帮助。 - bob marti
我已经复制了你的代码,但是我没有发现任何问题。你尝试在.py文件中运行它了吗? - Juan Antonio
1
在IPython中,您可以将参数列表传递给解析器。根据argparse文档:parser.parse_args(['--sum', '7', '-1', '42']) 或者 parser.parse_args('--sum 7 -1 42'.split() ) - nigel222
谢谢大家的即时帮助,指出我的错误并提供替代方法。我尝试了不同的方式,但都是用ipython而不是“正常”的*.py文件。 - Haik
请查看下面的答案。我花了3个小时研究,我认为我找到了真正的解决方案(它应该是被接受的答案,以帮助遇到同样问题的人)。我从这里获取了我的答案 https://dev59.com/UVYM5IYBdhLWcg3wfAGF - Francesco
8个回答

51

argparse 是一个用于解析从命令行传递的参数的模块,例如,如果您在命令提示符下键入以下内容:

$ python my_programme.py --arg1=5 --arg2=7
您可以使用argparse来解释--arg1=5 --arg2=7部分。如果argparse认为参数无效,它会退出,通常情况下,这是通过调用sys.exit()来在Python中实现的,这就是你看到的SystemExit错误。
因此,问题在于您正在尝试从交互式解释器(看起来像是IPython)中使用argparse,而此时程序已经启动,因此参数应该已经被解析了。
要正确尝试它,请创建一个单独的Python文件,例如my_programme.py,并使用命令行中的python运行它,就像我所演示的那样。

1
是的,确实是IPython,我想说非常感谢您清晰明了的回答!即使我已经花费了几个小时尝试自己解决这个问题,但似乎我还需要更多的时间来独立解决它。谢谢。 - Haik

38

[快速解决方案]在代码中添加一个虚拟解析器参数

parser.add_argument('-f')

4
好的,它起作用了,但您能否请提供一些关于它如何工作的解释? - Saksham Dubey
4
Jupyter-Notebook有一些默认的参数设置,其中之一是"-f"。import sys sys.argv运行上述代码将显示它们。 - johninvirtual
1
在我看来,这应该是被接受的答案。被接受的答案并不是一个解决方案,我的代码是一个Jupyter笔记本,我不能在命令行中将其作为脚本运行。 - Francesco

26

我曾遇到类似的问题。加入这些代码行后,问题得到了解决。

import sys
sys.argv=['']
del sys

5
为什么那个有帮助呢?你能为任何阅读它的人解释一下吗? - daevski
1
有用的答案,类似于 https://dev59.com/-V0a5IYBdhLWcg3wJlyo#60771872 - Debvrat Varshney

8

5

parse_args 方法在没有参数的情况下被调用时,会尝试解析 sys.argv 的内容。你的解释器进程填充了 sys.argv 的值,但这些值与你的 parser 实例支持的参数不匹配,因此解析失败。

尝试打印 sys.argv 以检查传递给解释器进程的参数。

尝试调用 parser.parse_args(['my', 'list', 'of', 'strings']) 来查看解析器如何处理使用不同 cmdline 参数启动的解释器。


1

解决这个问题有两种方法:

  1. 使用 get_ipython().__class__.__name__ 来确定我们是在 ipython 还是终端上运行,当我们在 ipython 上运行时,使用 parser.parse_args(args = [])

    try:
        get_ipython().__class__.__name__
        # 没有错误意味着我们正在运行 ipython
        args = parser.parse_args(args = []) # 重置 args
    except NameError:
        # NameError 意味着我们正在运行终端
        args = parser.parse_args()
    
  2. 使用 parser.parse_known_args() 将现有的 args 分别存储。我们将得到一个包含两个值的元组(第一个是由 add_argument 添加的 args,第二个是现有的 args)

    args = parser.parse_known_args()[0] # 允许未识别的参数
    
这两种方法的区别在于第二种方法允许未被识别的参数。它将被存储在返回的元组的第二个值中。

0

我知道这个问题已经快三年了,但是听起来可能很愚蠢,当你没有安装argparse而不是默认的“找不到该模块”错误消息时,也会产生这个退出错误。只是帮助那些可能也遇到这个错误的人。


4
怎么可能没有安装呢?这是一个标准库模块。 - Yaroslav Nikitenko

0
添加一个参数并分配一些值是可行的。我正在将args(ArgumentParser类型对象)从一个函数传递到另一个函数(不是在典型情况下,例如从终端获取用户参数)。
from argparse import ArgumentParser
parser = ArgumentParser()
# create and assign a dummy args
parser.add_argument('--myarg1')
args = parser.parse_args(['--myarg1', ''])

args.myarg2 = True  # actuals args assignment
myTargetFunction(args)  # passing args to another function  

我发现在解析器中没有实际参数时,parse_args() 会出错。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接