【问题标题】:How to iterate over function arguments如何迭代函数参数
【发布时间】:2011-02-24 03:39:04
【问题描述】:

我有一个 Python 函数,它接受多个字符串参数 def foo(a, b, c): 并将它们连接成一个字符串。 我想遍历所有函数参数以检查它们不是无。怎么做? 有没有快速将 None 转换为 "" 的方法?

谢谢。

【问题讨论】:

    标签: python arguments


    【解决方案1】:

    locals() 可能是您的朋友,如果您在函数中首先调用它。

    示例 1:

    >>> def fun(a, b, c):
    ...     d = locals()
    ...     e = d
    ...     print e
    ...     print locals()
    ... 
    >>> fun(1, 2, 3)
    {'a': 1, 'c': 3, 'b': 2}
    {'a': 1, 'c': 3, 'b': 2, 'e': {...}, 'd': {...}}
    

    示例 2:

    >>> def nones(a, b, c, d):
    ...     arguments = locals()
    ...     print 'The following arguments are not None: ', ', '.join(k for k, v in arguments.items() if v is not None)
    ... 
    >>> nones("Something", None, 'N', False)
    The following arguments are not None:  a, c, d
    

    回答:

    >>> def foo(a, b, c):
    ...     return ''.join(v for v in locals().values() if v is not None)
    ... 
    >>> foo('Cleese', 'Palin', None)
    'CleesePalin'
    

    更新:

    “示例 1”强调如果您的参数的顺序很重要,我们可能需要做一些额外的工作,因为 locals()(或 vars())返回的 dict 是无序的。上面的函数也不能非常优雅地处理数字。所以这里有一些改进:

    >>> def foo(a, b, c):
    ...     arguments = locals()
    ...     return ''.join(str(arguments[k]) for k in sorted(arguments.keys()) if arguments[k] is not None)
    ... 
    >>> foo(None, 'Antioch', 3)
    'Antioch3'
    

    【讨论】:

    • FWIW,我认为*args 是去这里的方式......如果你想连接十六个字符串怎么办?我只是想表明在 Python 中使用提供的函数签名是可能的 :-)
    • 你也可以使用 vars() 代替本地人。
    • @extraneon 感谢您的提示。在这种情况下,locals() 的行为似乎与 vars() 相同,但没有参数。
    • 发现这与将下划线分隔的字符串转换为驼峰式字符串的功能一起非常有用...可以在从 init 参数实例化对象属性时节省大量繁琐的样板代码。我还在等着让自己陷入这种编程风格的麻烦:P
    • 为了简化示例,将语句拆分为单独的行可能会有所帮助。 (即:for k in sorted(arguments.keys()):if arguments[k] is not None:print(str(arguments[k])))
    【解决方案2】:
    def func(*args):
        ' '.join(i if i is not None else '' for i in args)
    

    如果你加入一个空字符串,你可以做''.join(i for i in args if i is not None)

    【讨论】:

    • 如果所有参数都被显式声明了怎么办?就像在 def foo(a, b, c):
    • @Jack:重新定义你的功能。那将是最简单的选择。如果你只有几个参数,你可以把它们放到一个元组中。
    • @Jack:你为什么这么认为?这是惯用的 Python。你单独使用你的论点吗?如果您可以轻松地将args 解压缩为具有适当名称的变量。
    • @Jack 我同意你的看法。您可以显式命名您的参数,并在加入之前构建这些 args 的列表 (args = [a,b,c])。也许关键字构造也是一种解决方案;然后,您可以从 kwargs 字典中获取值。但是,关键字默认值可能会出现意外行为。
    • @extraneon 两天前我开始使用 Python,但我不确定我理解你的意思。
    【解决方案3】:

    您可以使用检查模块并定义这样的函数:

    import inspect
    def f(a,b,c):
        argspec=inspect.getargvalues(inspect.currentframe())
        return argspec
    f(1,2,3)
    ArgInfo(args=['a', 'b', 'c'], varargs=None, keywords=None, locals={'a': 1, 'c': 3, 'b': 2})
    

    在 argspec 中,您需要通过传递参数执行任何操作。

    使用接收到的 arg 信息来连接字符串就足够了:

    def f(a,b,c):
        argspec=inspect.getargvalues(inspect.currentframe())
        return ''.join(argspec.locals[arg] for arg in argspec.args)
    

    供参考: http://docs.python.org/library/inspect.html#inspect.getargvalues

    【讨论】:

      【解决方案4】:

      这也许是你想要的?

      def foo(a, b, c):
          "SilentGhost suggested the join"
          ' '.join(i if i is not None else '' for i in vars().values())
      
      def bar(a,b,c): 
          "A very usefull method!"
          print vars()
          print vars().values()
      

      注意vars() 的使用,它返回一个字典。

      【讨论】:

        【解决方案5】:

        我会使用 sed s/None//g,但这不是在 python 中,但你可以使用 os.popen() 来做到这一点。

        【讨论】:

        • 我认为None 表示python 对象None 而不是文字字符串"None"
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-26
        • 2017-05-28
        • 2020-09-07
        • 2020-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多