5

位置引数を任意の順序で部分的に設定することを定義したいとします。つまり、2番目と3番目の引数を修正する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はキーワード引数を使用せず、位置のみを使用します。

それらの引数を部分的に修正する方法は?ラムダとラッ​​パーの唯一の選択肢はありますか?

関数をインラインで定義する場合、たとえば関数を求める引数に対して関数を定義する場合のように、ラッパーは醜いです。ここではラムダ事実であり、パーシャルは他のオプションですが、この場合は不足しているようです。

4

2 に答える 2

6

でそれを行うことはできませんpartial。これは、キーワード引数を提供しないCAPIsplitの関数を使用しているためです。PyArg_ParseTuplePythonの観点からは、メソッドが次のように定義されている場合と同じです。

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「ほぼ同等」であると記載されています。

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']

そして、同じ問題を抱えていた他の多くのメソッド/関数についても同じことが言えます。

于 2013-03-26T18:57:33.437 に答える
5

str.rsplitあなたが本当にoperator.methodcaller()代わりに使いたいのなら:

>>> from operator import methodcaller
>>> SEP = ' '
>>> s = methodcaller('rsplit', SEP, 1)
>>> s('Test one two')
['Test one', 'two']
于 2013-03-26T18:26:53.863 に答える