web-dev-qa-db-ja.com

functools.partialは、キーワード引数として位置引数を使用したい

だから私はpartialを理解しようとしています:

import functools

def f(x,y) :
    print x+y

g0 = functools.partial( f, 3 )
g0(1)

4 # Works as expected

に:

g1 = functools.partial( f, y=3 )
g1(1)

4 # Works as expected

に:

g2 = functools.partial( f, x=3 )
g2(1)

TypeError: f() got multiple values for keyword argument 'x'

TypeErrorをキーワード引数として使用すると、yが消えます。

に:

g2( y=1 )

4

TypeErrorの原因は何ですか?

29
usual me

これは、実際には_functools.partial_とは何の関係もありません。基本的に、次のように関数を呼び出しています。

_f(1, x=3)
_

Pythonは最初に位置引数を実行し、最初の引数はxです。次に、キーワード引数が適用され、再びxが提供されます。

functools.partial()には、代わりにキーワード引数として最初の位置引数をすでに指定したことを検出する手段がありません。位置引数を_y=_キーワード引数に置き換えても、呼び出しは拡張されません。

位置引数とキーワード引数を混在させる場合は、同じ引数を2回使用しないように注意する必要があります。

34
Martijn Pieters

@ Martijn-Pietersの回答を拡張するために、これは2番目のパラメーターの位置的性質を保持する方法です。ここで、g2への引数はyとして位置的に渡されます。

def f(x,y) :
    print x+y

g2 = functools.partial( f, *[3] )
g2(1)

これは、fの引数の初期セットを置き換えようとしているときに機能します。 partialを使用して置き換える方法がわかりません。 3パラメーター関数の2番目の引数だけで、1番目と3番目を位置的に渡すことができます。しかし、ラムダ式でそれを行うことができます。

1
nealmcb

回答ではなく、フォローアップの質問です(50の評判がないとコメントを追加できないため)。ここでの回答は私の理解を超えているため、詳しく説明するか、簡単な用語を使用してください。 Mayaのボタンを使用して同様の問題が発生します

import maya.cmds as cmds
from functools import partial

class Myclass(object):
    def __init__(self):
        pass
    def createui(self):
        derp = cmds.window()
        cmds.formLayout()
        cmds.button(label = "w/e", c = partial(self.f, x = 3))
        cmds.showWindow(derp)
    def f(self, x = 5, y = 3, *_):
        print(x+y)

herp = Myclass()
herp.createui()

ボタンをクリックすると、「キーワード引数 'x'に複数の値があります」という同じエラーが発生します。

引数として送信されていると思っていたのはクラスの呼び出しでしたが、UI要素自体(通常はFalseの値)への愚かな呼び出しは、* _ catch all引数、次にxのキーワード引数に入れる必要があります。 。

0
rasonage