【问题标题】:How to parse (width)x(height) command-line argument into two arguments?如何将(宽度)x(高度)命令行参数解析为两个参数?
【发布时间】:2021-12-11 20:37:54
【问题描述】:

所以我的目标是输入80x40,然后输入size,然后以(80, 40)的格式返回。

但是如果我写80xdf,它会给出错误信息并使用默认值, 那么我还希望它在您编写arguments < 1 之一时给出错误。

此外,如果格式错误,它应该给出错误消息。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('width', type=int, help='width of the world')
parser.add_argument('x', type=int, help='x')
parser.add_argument('height', type=int, help='height of the world')
args = parser.parse_args()
if args.width and args.height < 1:
    print("Both width and height needs to have positive values above zero.")
    print("Using default world size: 80x40")
    size = tuple(80, 40)
elif args.format(args.width, args.x, args.height):
    size = tuple("{},{}".format(args.width, args.height))
else:
    print("World size should contain width and height, separated by ‘x’. Ex:'80x40'")
    print("Using default world size: 80x40")
    size = tuple(80, 40)

输入 -ws 80x40 -g 0 时遇到的错误:

usage: main.py [-h] width x height
main.py: error: argument width: invalid int value: '80x40'

【问题讨论】:

  • 您将“width”和“height”作为两个单独的参数,但将它们作为单个字符串“80x40”传递;尝试单独传递它们或相应地解析它们。
  • 您没有创建一个接受数字 x 数字的 cli 参数。您制作了 3 个 cli 参数,它们采用 3 个单独的整数。所以你可以给它80 0 40(0 是你将保存在x 中的内容)
  • @dsillman2000 所以如果我想输入 80x40,我应该先使用 split() 以便它们成为 3 个单独的字符串吗?
  • @BoarGules 这怎么是重复的?虽然这确实是代码的一个有效问题,但这不是问题所在。代码甚至还没有到达那部分。问题在于 OP 如何定义和传递参数。应该推荐该链接,而不是重复的目标...

标签: python argparse


【解决方案1】:

在您的 sn-p 中,您没有创建一个采用 NxM 的 cli 参数。您制作了 3 个 cli 参数,它们采用 3 个单独的(空格!)整数。

所以你可以输入例如80 0 40,它会解析(中间数字保存为x)。


最简单、开箱即用的解决方案是要求大小正好为 2 个整数。

parser = argparse.ArgumentParser()
parser.add_argument('size', nargs=2)
args = parser.parse_args()

size = args.size

或者像你一样的两个位置参数......但是没有那个 x “参数”并且在执行时没有写 x。

parser = argparse.ArgumentParser()
parser.add_argument('width')
parser.add_argument('height')
args = parser.parse_args()

size = args.width, args.height

这两个都需要你传递参数,只需要80 40,不需要 x,需要空格。

之后,您可以按照自己的假设行事。 正如 BoarGules 链接的那样,您搞砸了 and 的工作方式。

您的if args.width and args.height &lt; 1: 表示if args.width and (args.height &lt; 1):,任何非空非零值都是真实的。

应该是if args.width&lt;0 or args.height&lt;0 - 两个条件,你希望其中任何一个为真,因此or

【讨论】:

  • 感谢您的回答,但是我有什么办法可以通过输入 80x40 来做到这一点,因为任务是数据应该输入为 numberxnumber?
  • 获取一个字符串,拆分是手动使用.split('x')。检查结果是否正好有 2 个部分,以及这两个部分是否都解析为整数
【解决方案2】:

如果出于某种原因您真的想将参数作为80x40 传递,您可以使用自定义type 定义单个参数:

import argparse

def parse_world_size_arg(arg: str) -> tuple:
    """ Parse width and height from command argument. """
    return tuple(map(int, arg.split('x')))

parser = argparse.ArgumentParser()
parser.add_argument('size', type=parse_world_size_arg, help='widthxheight of the world')

args = parser.parse_args()
print(args.size)

如果上面的代码以python main.py 80x40 运行,输出将是:

(80, 40)

然后你可以根据需要添加一些输入验证:

def parse_world_size_arg(arg: str) -> tuple:
    """ Parse width and height from command argument. """
    try:
        return tuple(map(int, arg.split('x')))
    except ValueError:
        return tuple()

...
args = parser.parse_args()
size = (80, 40)
if len(args.size) != 2:
    print("World size should contain width and height, separated by ‘x’. Ex:'80x40'")
    print("Using default world size: 80x40")
elif any(dim < 1 for dim in args.size):
    print("Both width and height need to have positive values above zero.")
    print("Using default world size: 80x40")
else:
    size = args.size

【讨论】:

  • 不幸的是我仍然得到:用法:gol.py [-h] [-g GENERATIONS] [-s SEED] [-ws WORLDSIZE] [-f FILE] gol.py:错误:无法识别的参数: 80x40
  • 因为这与您在问题中给出的解析器定义完全不同...显然您需要python main.py -ws 80x40
  • @Snapy 你成功了吗?
  • 不,但我会尝试“同时尝试除外”,但我专注于其他事情 atm :)
猜你喜欢
  • 1970-01-01
  • 2022-01-11
  • 2011-04-27
  • 2019-09-04
  • 1970-01-01
  • 2013-03-21
相关资源
最近更新 更多