【问题标题】:Python argparse: args has no attribute funcPython argparse:args 没有属性 func
【发布时间】:2018-07-16 19:29:51
【问题描述】:

简介

我在学校项目上遇到了麻烦。我正在制作一个测试套件,我需要一个配置生成接口和一个测试运行器。为此,我使用了库 argparse 和两个子解析器 cgirun

问题本身

所以这里是失败的代码部分:

def CGI(args):
    print("CGI: Work In Progress")
    exit(0)


def runTest(args):
    print("Run: Work in Progress")
    exit(0)

parser = argparse.ArgumentParser()
subparser = parser.add_subparsers()
cgi = subparser.add_parser("cgi", help="CSV Generator Interface")
run = subparser.add_parser("run", help="Test running")
verbosity = parser.add_argument_group("Verbosity").add_mutually_exclusive_group()
check = run.add_argument_group("Checks")

# Arguments
#Run parser
run.set_defaults(func=runTest)

# Run argument declaration ...

# Verbosity argument declaration ...

# Check argument declaration ...

#CGI
cgi.set_defaults(func=CGI)

args = parser.parse_args()
args.func(args) # Error is here

每当我运行此代码时,我都会遇到以下错误:

  File "/home/thor/Projects/EPITA/TC/test/test.py", line 44, in main
    args.func(args)
AttributeError: 'Namespace' object has no attribute 'func'

Python 版本

$ python -V
Python 3.6.4

Argparse 版本

$ pip show argparse
Name: argparse
Version: 1.4.0
Summary: Python command-line parsing library
Home-page: https://github.com/ThomasWaldmann/argparse/
Author: Thomas Waldmann
Author-email: tw@waldmann-edv.de
License: Python Software Foundation License
Location: /usr/lib/python3.6/site-packages
Requires: 

编辑

如果我手动安装 argparse,它可以工作 sudo pip install argparse。但是有没有本地解决方案。我不确定它是否可以在学校的计算机上运行(我们不能安装软件包)

编辑 2

好吧,我的错,我是个彻头彻尾的白痴,我没有重写我的运行脚本,所以我忘了输入runcgi

感谢您阅读我的信息和您未来的帮助:)

【问题讨论】:

  • 是的,没错。您了解了子解析器(包括它们的默认值)仅在其各自的命令出现在参数中时才运行的艰难方法。请注意,您可以回答自己的问题。
  • 推荐的解决方案是p1 = parser.add_subparsers(required=True, dest='cmd')bugs.python.org/issue16308#msg350415

标签: python


【解决方案1】:

这是 Python 3 版本的 argparse (https://bugs.python.org/issue16308) 中的一个已知错误。在 Python 2 中,如果在没有任何参数的情况下调用脚本(即没有子命令),它会以“错误:参数太少”干净地退出。然而,在 Python3 中,您会得到一个未处理的 AttributeError。幸运的是,解决方法非常简单:

    try:
        func = args.func
    except AttributeError:
        parser.error("too few arguments")
    func(args)

【讨论】:

    【解决方案2】:
    parser = ArgumentParser()
    parser.set_defaults(func=lambda args: parser.print_help())
    

    imho 比 try..except 更好

    【讨论】:

      【解决方案3】:

      另一种解决方案可能是:

      if len(args.__dict__) <= 1:
          # No arguments or subcommands were given.
          parser.print_help()
          parser.exit()
      

      【讨论】:

        【解决方案4】:

        或者,@simleo 和 @nehaljwani 的答案的组合:

            # Parse the arguments and call the sub command
            args = parser.parse_args()
            try:
                args.func(args)
            except AttributeError:
                parser.print_help()
                parser.exit()
        

        【讨论】:

        • 没错,是要发布相同的,但没有将 args 传递给 func,只是在 try 中的 args.func
        【解决方案5】:

        此错误仅在您直接运行“python script.py”时发生。 'python script.py --help' 工作正常。

        添加

        args = parser.parse_args()
        try:
            args.func(args)
        except AttributeError:
            parser.print_help()
            parser.exit()
        

        将帮助您处理这种直接运行“python script.py”的情况。 解决了我的问题,非常感谢!

        【讨论】:

          【解决方案6】:

          您必须制作不带参数调用脚本所需的子解析器。为此,您必须为 parser.add_subparsers 指定 destrequired 参数:

          parser = argparse.ArgumentParser()
          subparser = parser.add_subparsers(dest='cmd', required=True)
          

          请注意,对于 Python 3.6 及更早版本,没有 required 参数,您必须为 subparser 对象显式设置它:

          subparser.required = True
          

          此 SO 答案中提供了详细信息:Argparse with required subparser

          【讨论】:

            猜你喜欢
            • 2020-10-03
            • 1970-01-01
            • 1970-01-01
            • 2017-03-05
            • 2018-06-09
            • 1970-01-01
            • 2010-10-05
            • 2014-05-14
            • 1970-01-01
            相关资源
            最近更新 更多