【问题标题】:Can functools.partial be used to bind arbitrary positional arguments?functools.partial 可以用来绑定任意位置参数吗?
【发布时间】:2013-03-16 16:42:03
【问题描述】:

假设你想定义一个 partial 以任意顺序设置位置参数,即你想将 partial 应用到 str.split修复第二个和第三个参数。想要的结果是一样的:

lambda s: str.rsplit(s, SEP, 1) # SEP given.

(我使用str.rsplit(s... 而不是s.rsplit(... 以更清楚地说明这一点)。

使用 functools.partial 的一些近似值是:

partial(str.rsplit, sep=SEP, maxsplit=1) # SEP given

但是 str.rsplit 不使用关键字参数,只使用位置参数。

如何部分解决这些参数? lamda 和 wrappers 是唯一的选择吗?

如果你想内联定义函数,包装器是丑陋的,比如为一个函数的参数定义它。 Lambda 是这里的 defacto,而 partial 是另一种选择,但在这种情况下似乎缺乏。

【问题讨论】:

    标签: python


    【解决方案1】:

    partial 无法做到这一点。这是因为 split 使用 C API 中的 PyArg_ParseTuple 函数,该函数不提供关键字参数。从python的角度来看,如果方法被定义为:

    def split(self, *args):
        if len(args) > 2:
            raise TypeError(...)
        sep = args[0] if args else None
        maxsplit = args[1] if len(args) > 1 else -1
        ...
    

    Partial 只能按顺序分配位置参数。这在documentation 中提到,他们在其中声明partial“大致相当于”:

    def partial(func, *args, **keywords):
        def newfunc(*fargs, **fkeywords):
            newkeywords = keywords.copy()
            newkeywords.update(fkeywords)
            return func(*(args + fargs), **newkeywords)
        newfunc.func = func
        newfunc.args = args
        newfunc.keywords = keywords
        return newfunc
    

    注意return func(*(args + fargs), **newkeywords),它清楚地表明您传递给partial 的参数被附加到其他函数参数之前。

    结论是lambdapartial 更强大。

    附带说明,在 python3.3 中,您可以指定 maxsplit 作为关键字参数:

    >>> 'some string with spaces'.split(maxsplit=2)
    ['some', 'string', 'with spaces']
    

    对于存在相同问题的许多其他方法/函数也是如此。

    【讨论】:

    • 坦克! return func(*(args + fargs), **newkeywords) 是关键。
    • 应该扩展你相当中肯的评论 re: lambdas 来举例说明这种情况。
    【解决方案2】:

    对于str.rsplit,您确实想改用operator.methodcaller()

    >>> from operator import methodcaller
    >>> SEP = ' '
    >>> s = methodcaller('rsplit', SEP, 1)
    >>> s('Test one two')
    ['Test one', 'two']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 2011-04-21
      • 2014-02-13
      • 1970-01-01
      相关资源
      最近更新 更多