【问题标题】:How to iterate over arguments如何迭代参数
【发布时间】:2015-01-26 15:58:56
【问题描述】:

我有这样的脚本:

import argparse

parser = argparse.ArgumentParser(
                description='Text file conversion.'
                )
parser.add_argument("inputfile",   help="file to process", type=str)
parser.add_argument("-o", "--out", default="output.txt",
                    help="output name")
parser.add_argument("-t", "--type", default="detailed",
                    help="Type of processing")

args = parser.parse_args()

for arg in args:
    print(arg)

但它不起作用。我得到错误:

TypeError: 'Namespace' object is not iterable

如何迭代参数及其值?

【问题讨论】:

    标签: python argparse


    【解决方案1】:

    Namespace 对象不可迭代,如果您需要字典,标准文档建议执行以下操作:

    >>> vars(args)
    {'foo': 'BAR'}
    

    所以

    for key,value in vars(args).iteritems():
        # do stuff
    

    老实说,我不确定您为什么要迭代参数。这在某种程度上违背了使用参数解析器的目的。

    【讨论】:

    • 一个典型的用法是实现debug-input 模式,其中脚本打印出所有输入参数并退出;对于确保正确解释日期时间输入值之类的东西很有用
    • 注意,iteritems() 在 Python 2.x 中,items() 在 Python 3.x 中。
    • 关于最后一句话,你可以有一个基于配置文件解析命令行参数的元程序
    【解决方案2】:

    如果您想遍历命名空间对象,请添加“vars”:

     for arg in vars(args):
         print arg, getattr(args, arg)
    

    【讨论】:

    • 在 Python 3 中:for arg in vars(args): print(arg, getattr(args, arg))
    【解决方案3】:

    ArgumentParser.parse_args 返回 Namespace 对象而不是可迭代数组。

    供您参考,https://docs.python.org/3/library/argparse.html#parsing-arguments

    ArgumentParser parses arguments through the parse_args() method. This will inspect the command line, convert each argument to the appropriate type and then invoke the appropriate action.
    

    而且它不应该那样使用。考虑您的用例,在文档中,它说 argparse 将弄清楚如何从 sys.argv 中解析出这些。,这意味着您不必遍历这些参数。 p>

    【讨论】:

      【解决方案4】:

      之后

      args = parser.parse_args()
      

      要显示参数,请使用:

      print args # or print(args) in python3
      

      args 对象(argparse.Namespace 类型)不可迭代(即不是列表),但它有一个 .__str__ 方法,可以很好地显示值。

      args.outargs.type 给出您定义的 2 个参数的值。这在大多数情况下都有效。 getattr(args, key) 访问值的最通用方式,但通常不需要。

      vars(args)
      

      将命名空间转换为字典,您可以使用所有字典方法访问该字典。这在docs 中有详细说明。

      参考:文档的命名空间段落 - https://docs.python.org/2/library/argparse.html#the-namespace-object

      【讨论】:

      • 感谢您的精彩文章!
      【解决方案5】:

      我正在使用args.__dict__,它可以让您访问底层的 dict 结构。 然后,它是一个简单的键值迭代:

      for k in args.__dict__:
        print k, args.__dict__[k]
      

      【讨论】:

        【解决方案6】:

        从解析器中解析 _actions 似乎是一个不错的主意。而不是运行 parse_args() 然后尝试从你的命名空间中挑选东西。

        import argparse
        
        parser = argparse.ArgumentParser(
                        description='Text file conversion.')
        parser.add_argument("inputfile", help="file to process", type=str)
        parser.add_argument("-o", "--out", default="output.txt",
                        help="output name")
        parser.add_argument("-t", "--type", default="detailed",
                        help="Type of processing")
        options = parser._actions
        for k in options:
            print(getattr(k, 'dest'), getattr(k, 'default'))  
        

        您可以将“dest”部分修改为“选择”,例如,如果您需要为另一个脚本中的参数预设默认值(例如,通过返回函数中的选项)。

        【讨论】:

          【解决方案7】:

          使用内置的 dict() 类来迭代 args 非常简单,而且效果很好:

          args = parser.parse_args()
          args_dict = dict(vars(args))
          for i, ii in args_dict.items():
               print(i, ii)
          

          来自builtins.py

              def __init__(self, seq=None, **kwargs): # known special case of dict.__init__
                  """
                  dict() -> new empty dictionary
                  dict(mapping) -> new dictionary initialized from a mapping object's
                      (key, value) pairs
                  dict(iterable) -> new dictionary initialized as if via:
                      d = {}
                      for k, v in iterable:
                          d[k] = v
                  dict(**kwargs) -> new dictionary initialized with the name=value pairs
                      in the keyword argument list.  For example:  dict(one=1, two=2)
                  # (copied from class doc)
                  """
                  pass
          

          【讨论】:

            猜你喜欢
            • 2011-02-24
            • 2015-08-15
            • 1970-01-01
            • 2021-07-21
            • 1970-01-01
            • 2011-01-20
            • 1970-01-01
            • 1970-01-01
            • 2017-02-11
            相关资源
            最近更新 更多