假设您要以任意顺序定义部分设置位置参数,即您希望将部分应用于 str.split 修复第2和第3个参数。期望的结果与:
相同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和包装器吗?
如果你想定义内联函数,包装器是丑陋的,比如为一个函数的参数定义它。 Lambda 在这里是 defacto , partial 是另一种选择,但在这种情况下似乎缺乏。
答案 0 :(得分:4)
对于str.rsplit
,您确实想要使用operator.methodcaller()
:
>>> from operator import methodcaller
>>> SEP = ' '
>>> s = methodcaller('rsplit', SEP, 1)
>>> s('Test one two')
['Test one', 'two']
答案 1 :(得分:4)
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
的参数被添加到其他函数参数之前。
结论是lambda
比partial
更强大。
另外,在python3.3中,您可以将maxsplit
指定为关键字参数:
>>> 'some string with spaces'.split(maxsplit=2)
['some', 'string', 'with spaces']
对于具有相同问题的许多其他方法/功能也是如此。