如何将(宽度)x(高度)命令行参数解析为两个参数?

Posted

技术标签:

【中文标题】如何将(宽度)x(高度)命令行参数解析为两个参数?【英文标题】:How to parse (width)x(height) command-line argument into two arguments? 【发布时间】: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 中的内容) 这能回答你的问题吗? Why does "a == x or y or z" always evaluate to True? @dsillman2000 所以如果我想输入 80x40,我应该先使用 split() 以便它们成为 3 个单独的字符串吗? @BoarGules 这怎么是重复的?虽然这确实是代码的一个有效问题,但这不是问题所在。代码甚至还没有到达那部分。问题在于 OP 如何定义和传递参数。应该推荐该链接,而不是重复的目标... 【参考方案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 :)

以上是关于如何将(宽度)x(高度)命令行参数解析为两个参数?的主要内容,如果未能解决你的问题,请参考以下文章

Python 命令行参数解析: optparse 模块

如何在C++中解析命令行参数

使用多个参数解析命令行选项 [getopt?]

在将对象添加到场景后如何更新宽度,高度? Three.PlaneGeometry(宽度,高度,1,1)

将字符串拆分(不解析)到命令行参数 C# [重复]

如何解析命令行参数?