Argparse 参数数量限制

发布于 2025-01-14 10:29:24 字数 2746 浏览 1 评论 0原文

我正在尝试将 bash 脚本转换为 python 脚本,并且必须使用 Argparser 创建很多参数。 当我使用此参数运行代码时,我收到错误

'
  File "/home/lmonari/anaconda3/envs/ChemFlowOfficial/lib/python3.9/argparse.py", line 338, in _format_usage
    assert ' '.join(opt_parts) == opt_usage

AssertionError'

如果我随机注释一些参数,则代码可以正常工作。 我是否已达到 Argparse 的最大参数数?我没有在任何地方找到记录的限制

代码:

为命令行创建解析器

parser = argparse.ArgumentParser(add_help=False)

# format the argument groups
parser._action_groups.pop()

# help arguments
help_args = parser.add_argument_group('[ Help ] ')
help_args.add_argument('-h', '--help', action='store_true',
                       help='Show this help message and exit.' )
help_args.add_argument("-H","--Help", action='help',
                    help="Detailed help.")                       

# checking the short help from the terminal_input
terminal_input=sys.argv
if '-h' in terminal_input or '--help' in terminal_input:
    DockFlow_help_short()
    parser.exit()
    
# required arguments
required = parser.add_argument_group('[ Required ] ')
required.add_argument('-p',"---project", metavar='',
                    help="STR : ChemFlow project.")
# required.add_argument("-r","--receptor", metavar='',
#                     help="Receptor's mol2 file.", required=True)
# required.add_argument("-l","--ligand", metavar='',
#                     help="FILE : Ligands  MOL2 file.", required=True) 
# required.add_argument("-dp","--program", metavar='',
#                     help="STR : plants, vina, qvina, smina.", required=True) 

# post processing
post_pro = parser.add_argument_group('[ Post Processing ]')
post_pro.add_argument("--postprocess", metavar='',
                      help="Process DockFlow output for the specified project/protocol/receptor.")
post_pro.add_argument("--postprocess-all", metavar='',
                      help="Process DockFlow output in a ChemFlow project.")
post_pro.add_argument('-n',"--n_poses", metavar='',
                      help="INT : Number of docked poses to keep.")
# post_pro.add_argument("--archive", metavar='',
#                       help="Compress the docking folders for the specified project/protocol/receptor.")
# post_pro.add_argument("--archive_all", metavar='',
#                       help="Compress the docking folders in a ChemFLow project.")


# optional argument
optional = parser.add_argument_group('[ Optional ]')
# optional.add_argument("-t","--test", metavar='',
#                     help="STR : Name for this specific protocol [default].") 
# optional.add_argument("-z",'--zeta', default="It's a trap", metavar='',
#                     help="testline", action=None) 

optional.add_argument('--foo', help=argparse.SUPPRESS)

parser.parse_args()

I'm trying to convert a bash script into a python script, and I have to create a lot of argument with Argparser.
When I run the code with this arguments I obtain the error

'
  File "/home/lmonari/anaconda3/envs/ChemFlowOfficial/lib/python3.9/argparse.py", line 338, in _format_usage
    assert ' '.join(opt_parts) == opt_usage

AssertionError'

If I randomly comment some arguments, the code works fine.
Have I reached the maximum number of arguments for Argparse? I don't find anywhere a documented limit

The code:

create a parser for command line

parser = argparse.ArgumentParser(add_help=False)

# format the argument groups
parser._action_groups.pop()

# help arguments
help_args = parser.add_argument_group('[ Help ] ')
help_args.add_argument('-h', '--help', action='store_true',
                       help='Show this help message and exit.' )
help_args.add_argument("-H","--Help", action='help',
                    help="Detailed help.")                       

# checking the short help from the terminal_input
terminal_input=sys.argv
if '-h' in terminal_input or '--help' in terminal_input:
    DockFlow_help_short()
    parser.exit()
    
# required arguments
required = parser.add_argument_group('[ Required ] ')
required.add_argument('-p',"---project", metavar='',
                    help="STR : ChemFlow project.")
# required.add_argument("-r","--receptor", metavar='',
#                     help="Receptor's mol2 file.", required=True)
# required.add_argument("-l","--ligand", metavar='',
#                     help="FILE : Ligands  MOL2 file.", required=True) 
# required.add_argument("-dp","--program", metavar='',
#                     help="STR : plants, vina, qvina, smina.", required=True) 

# post processing
post_pro = parser.add_argument_group('[ Post Processing ]')
post_pro.add_argument("--postprocess", metavar='',
                      help="Process DockFlow output for the specified project/protocol/receptor.")
post_pro.add_argument("--postprocess-all", metavar='',
                      help="Process DockFlow output in a ChemFlow project.")
post_pro.add_argument('-n',"--n_poses", metavar='',
                      help="INT : Number of docked poses to keep.")
# post_pro.add_argument("--archive", metavar='',
#                       help="Compress the docking folders for the specified project/protocol/receptor.")
# post_pro.add_argument("--archive_all", metavar='',
#                       help="Compress the docking folders in a ChemFLow project.")


# optional argument
optional = parser.add_argument_group('[ Optional ]')
# optional.add_argument("-t","--test", metavar='',
#                     help="STR : Name for this specific protocol [default].") 
# optional.add_argument("-z",'--zeta', default="It's a trap", metavar='',
#                     help="testline", action=None) 

optional.add_argument('--foo', help=argparse.SUPPRESS)

parser.parse_args()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄荷梦 2025-01-21 10:29:24

如果我取消注释所有参数,并在足够宽的屏幕上使用 parser.print_usage() ,我会得到

1155:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p] -r  -l  -dp  [--postprocess] [--postprocess-all] [-n] [--archive] [--archive_all] [-t] [-z]

在较窄的屏幕上它尝试将用法分成几行,并点击

1155:~/mypy$ python3 stack71486789.py 
Traceback (most recent call last):
  File "stack71486789.py", line 56, in <module>
    parser.print_usage()
  File "/usr/lib/python3.8/argparse.py", line 2501, in print_usage
    self._print_message(self.format_usage(), file)
  File "/usr/lib/python3.8/argparse.py", line 2467, in format_usage
    return formatter.format_help()
  File "/usr/lib/python3.8/argparse.py", line 294, in format_help
    help = self._root_section.format_help()
  File "/usr/lib/python3.8/argparse.py", line 225, in format_help
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.8/argparse.py", line 225, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.8/argparse.py", line 349, in _format_usage
    assert ' '.join(opt_parts) == opt_usage

使用格式化程序很脆弱。如果上面显示的用法太长,请尝试将其拆分。 assert 应该检查分割是否正确完成。元变量把事情搞砸了。这个问题是众所周知的。

如果我注释掉所有 metavar ,则有效的多行用法是:

1202:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p PROJECT] -r RECEPTOR -l LIGAND -dp PROGRAM [--postprocess POSTPROCESS]
                        [--postprocess-all POSTPROCESS_ALL] [-n N_POSES] [--archive ARCHIVE] [--archive_all ARCHIVE_ALL]
                        [-t TEST] [-z ZETA]

并且完整帮助

1203:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p PROJECT] -r RECEPTOR -l LIGAND -dp PROGRAM [--postprocess POSTPROCESS]
                        [--postprocess-all POSTPROCESS_ALL] [-n N_POSES] [--archive ARCHIVE] [--archive_all ARCHIVE_ALL]
                        [-t TEST] [-z ZETA]

[ Help ] :
  -h, --help            Show this help message and exit.
  -H, --Help            Detailed help.

[ Required ] :
  -p PROJECT, ---project PROJECT
                        STR : ChemFlow project.
  -r RECEPTOR, --receptor RECEPTOR
                        Receptor's mol2 file.
  -l LIGAND, --ligand LIGAND
                        FILE : Ligands MOL2 file.
  -dp PROGRAM, --program PROGRAM
                        STR : plants, vina, qvina, smina.

[ Post Processing ]:
  --postprocess POSTPROCESS
                        Process DockFlow output for the specified project/protocol/receptor.
  --postprocess-all POSTPROCESS_ALL
                        Process DockFlow output in a ChemFlow project.
  -n N_POSES, --n_poses N_POSES
                        INT : Number of docked poses to keep.
  --archive ARCHIVE     Compress the docking folders for the specified project/protocol/receptor.
  --archive_all ARCHIVE_ALL
                        Compress the docking folders in a ChemFLow project.

[ Optional ]:
  -t TEST, --test TEST  STR : Name for this specific protocol [default].
  -z ZETA, --zeta ZETA  testline

没有特殊字符或空白的较短 metavar 也应该可以工作。

If I uncomment all your arguments, and use a parser.print_usage() on a wide enough screen I get

1155:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p] -r  -l  -dp  [--postprocess] [--postprocess-all] [-n] [--archive] [--archive_all] [-t] [-z]

On a narrower screen it tries to split usage into several lines, and hits

1155:~/mypy$ python3 stack71486789.py 
Traceback (most recent call last):
  File "stack71486789.py", line 56, in <module>
    parser.print_usage()
  File "/usr/lib/python3.8/argparse.py", line 2501, in print_usage
    self._print_message(self.format_usage(), file)
  File "/usr/lib/python3.8/argparse.py", line 2467, in format_usage
    return formatter.format_help()
  File "/usr/lib/python3.8/argparse.py", line 294, in format_help
    help = self._root_section.format_help()
  File "/usr/lib/python3.8/argparse.py", line 225, in format_help
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.8/argparse.py", line 225, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
  File "/usr/lib/python3.8/argparse.py", line 349, in _format_usage
    assert ' '.join(opt_parts) == opt_usage

The usage formatter is brittle. If the usage as displayed above is too long, tries to split it. The assert is supposed to check that the split was done right. The metavars are messing that up. This problem is well known.

If I comment out all the metavar, the working multiline usage is:

1202:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p PROJECT] -r RECEPTOR -l LIGAND -dp PROGRAM [--postprocess POSTPROCESS]
                        [--postprocess-all POSTPROCESS_ALL] [-n N_POSES] [--archive ARCHIVE] [--archive_all ARCHIVE_ALL]
                        [-t TEST] [-z ZETA]

and full help

1203:~/mypy$ python3 stack71486789.py 
usage: stack71486789.py [-h] [-H] [-p PROJECT] -r RECEPTOR -l LIGAND -dp PROGRAM [--postprocess POSTPROCESS]
                        [--postprocess-all POSTPROCESS_ALL] [-n N_POSES] [--archive ARCHIVE] [--archive_all ARCHIVE_ALL]
                        [-t TEST] [-z ZETA]

[ Help ] :
  -h, --help            Show this help message and exit.
  -H, --Help            Detailed help.

[ Required ] :
  -p PROJECT, ---project PROJECT
                        STR : ChemFlow project.
  -r RECEPTOR, --receptor RECEPTOR
                        Receptor's mol2 file.
  -l LIGAND, --ligand LIGAND
                        FILE : Ligands MOL2 file.
  -dp PROGRAM, --program PROGRAM
                        STR : plants, vina, qvina, smina.

[ Post Processing ]:
  --postprocess POSTPROCESS
                        Process DockFlow output for the specified project/protocol/receptor.
  --postprocess-all POSTPROCESS_ALL
                        Process DockFlow output in a ChemFlow project.
  -n N_POSES, --n_poses N_POSES
                        INT : Number of docked poses to keep.
  --archive ARCHIVE     Compress the docking folders for the specified project/protocol/receptor.
  --archive_all ARCHIVE_ALL
                        Compress the docking folders in a ChemFLow project.

[ Optional ]:
  -t TEST, --test TEST  STR : Name for this specific protocol [default].
  -z ZETA, --zeta ZETA  testline

Shorter metavar without special characters or blank should also work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文