【问题标题】:argparse returns nested value for only 1 namespaceargparse 仅返回 1 个命名空间的嵌套值
【发布时间】:2017-07-05 21:32:12
【问题描述】:

我正在尝试为以下在远程服务器上执行的 .py 文件获取多个命名空间:

cmd = 'ssh root@{0} 2>/dev/null "/root/abc.py  {1} {2} {3} {4} {5} {6} {7} {8}"'.format(hostname, from_vm, to_vm, from_slot, to_slot, from_port, to_port, from_vm_inst, to_vm_inst)

除了主机名,所有其他实体都是列表。

在 abc.py 中,我有以下代码:

parser = argparse.ArgumentParser()
parser.add_argument(nargs='+', dest='from_vm',
                    help='list of name of source VMs')
print("List of items: {}".format(args.from_vm))

这会返回以下内容:

项目列表:['[myvm-r1-1,', 'myvm-r1-1,', 'myvm-r2-1,', 'myvm-r1-1,', 'myvm-r1- 1,', 'myvm-r2-1,', 'myvm-r2-1,', 'myvm-r1-1]', '[myvm-r2-1,', 'myvm-r2-1,', 'myvm-spt,', 'myvm-spt,', 'myvm-r1-1,', 'myvm-spt,', 'myvm-r2-1,', 'myvm-spt]', '[1, ', '1,', '1,', '1,', '1,', '1,', '1,', '1]', '[1,', '1,', '1 ,', '1,', '1,', '1,', '1,', '1]', '[2,', '3,', '1,', '1,', ' 5,', '2,', '4,', '4]', '[3,', '6,', '1,', '3,', '6,', '4,', '5,', '2]', '[instance-000000bc,', 'instance-000000bc,', 'instance-000000bf,', 'instance-000000bc,', 'instance-000000bc,', 'instance-000000bf ,', 'instance-000000bf,', 'instance-000000bc]', '[instance-000000bf,', 'instance-000000bf,', 'instance-000000c0,', 'instance-000000c0,', 'instance-000000bc ,', 'instance-000000c0,', 'instance-000000bf,', 'instance-000000c0]']

只有 1 个命名空间与此关联:

命名空间(from_vm=['[myvm-r1-1,', 'myvm-r1-1,', 'myvm-r2-1,', 'myvm-r1-1,', 'myvm-r1- 1,', 'myvm-r2-1,', 'myvm-r2-1,', 'myvm-r1-1]', '[myvm-r2-1,', 'myvm-r2-1,', 'myvm-spt,', 'myvm-spt,', 'myvm-r1-1,', 'myvm-spt,', 'myvm-r2-1,', 'myvm-spt]', '[1, ', '1,', '1,', '1,', '1,', '1,', '1,', '1]', '[1,', '1,', '1 ,', '1,', '1,', '1,', '1,', '1]', '[2,', '3,', '1,', '1,', ' 5,', '2,', '4,', '4]', '[3,', '6,', '1,', '3,', '6,', '4,', '5,', '2]', '[instance-000000bc,', 'instance-000000bc,', 'instance-000000bf,', 'instance-000000bc,', 'instance-000000bc,', 'instance-000000bf ,', 'instance-000000bf,', 'instance-000000bc]', '[instance-000000bf,', 'instance-000000bf,', 'instance-000000c0,', 'instance-000000c0,', 'instance-000000bc ,', 'instance-000000c0,', 'instance-000000bf,', 'instance-000000c0]'])

这在我看来是一个嵌套列表。我希望这个嵌套列表中的每个列表都有不同的命名空间,但没有成功。我尝试使用单独的 parser.add_argument 和单独的 dest=xyz,但没有成功。有人可以帮忙吗?我的要求是每个列表都有不同的命名空间。

【问题讨论】:

  • 您是否在代码示例中省略了args = parser.parse_args() 命令?
  • @hpaulj,我的代码里有,只是我在上面的例子中没有提到。

标签: argparse


【解决方案1】:

args = parser.parse_args() 返回一个 argparse.Namespace 对象。在您的情况下,它会生成一个具有一个属性的对象,args.from_vm。

from_vm 是一个命名空间对象的属性。我认为您不想要多个“命名空间”,而是想要一个子列表列表,或者可能是多个属性,每个属性都有自己的字符串列表。

该属性是 64 个字符串的列表。第一个元素是 ''[myvm-r1-1,',它看起来像嵌套列表的开始,但不是。它只是一个字符串。

看看sys.argv。解析器使用sys.argv[1:] 中的字符串列表。该列表由 shell 和 python 解释器确定。

使用nargs='+',解析器只需将整个列表存储到from_vm 属性 - 原样,无需更改。

如果您不喜欢 sys.argv[1:] 中的内容,请尝试在命令行中添加引号。做对了,这会将整个内容作为一个字符串传递,然后您可以以自己的方式对其进行解析。 JSON 已用于处理看起来像嵌套列表和/或字典的一般字符串。

另一种选择是将列表像输出一样写入文件,然后分别读取和解析。通过命令行和 argparse 传递它可能不值得付出努力。将它们用于简单的输入,例如文件名。

我在你的帖子的复制粘贴上做了一个' '.join(args.from_vm),得到了

In [123]: txt=' '.join(_)
In [124]: txt
Out[124]: '[myvm-r1-1, myvm-r1-1, myvm-r2-1, myvm-r1-1, myvm-r1-1, myvm-r2-1, myvm-r2-1, myvm-r1-1] [myvm-r2-1, ...instance-000000c0]'

即使您可以将它作为一个字符串加载,这也不会是一个简单的解析。

如果您可以像这样格式化输入字符串,解析会容易得多

--arg1 myvm-r1-1 myvm-r1-1 myvm-r2-1 myvm-r1-1 myvm-r1-1 myvm-r2-1 myvm-r2-1 myvm-r1-1
--arg2 myvm-r2-1 myvm-r2-1 myvm-spt myvm-spt myvm-r1-1 myvm-spt myvm-r2-1 myvm-spt
--arg3 1 1 1 1 1 1 1 1
--arg4 1 1 1 1 1 1 1 1 ...

也就是说,而不是带有, 单独术语的列表列表;用标志分隔列表,并省略[],。

【讨论】:

  • 我使用了 sys.argv[1:] ,然后使用了 ' '.join(sys.argv[1:]) ,它在删除引号后产生了一个字符串。然后我使用了 slash[(.*?)slash] 模式匹配来分隔方括号。然后我使用 split(",") 这个匹配的模式将它转换回列表。这符合我的目的。感谢 hpaulj 的帮助。
猜你喜欢
  • 2013-09-11
  • 1970-01-01
  • 2015-01-08
  • 2011-01-06
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
相关资源
最近更新 更多