539

**kwargsデフォルト値に関して、Pythonで使用する適切な方法は何ですか?

kwargs辞書を返しますが、デフォルト値を設定するための最良の方法は何ですか、それともありますか?辞書としてアクセスするだけでいいですか?get関数を使用しますか?

class ExampleClass:
    def __init__(self, **kwargs):
        self.val = kwargs['val']
        self.val2 = kwargs.get('val2')

簡単な質問ですが、良いリソースを見つけることができません。人々は私が見たコードでそれをさまざまな方法で行い、何を使用するかを知るのは難しいです。

4

14 に答える 14

569

get()ディクショナリにないキーのデフォルト値をに渡すことができます。

self.val2 = kwargs.get('val2',"default value")

ただし、特定のデフォルト値で特定の引数を使用することを計画している場合は、そもそも名前付き引数を使用しないのはなぜですか?

def __init__(self, val2="default value", **kwargs):
于 2009-07-08T14:47:38.040 に答える
293

ほとんどの答えはそれを言っていますが、例えば、

def f(**kwargs):
    foo = kwargs.pop('foo')
    bar = kwargs.pop('bar')
    ...etc...

「と同じ」です

def f(foo=None, bar=None, **kwargs):
    ...etc...

本当じゃない。後者の場合、fはとして呼び出すことができますがf(23, 42)、前者の場合は名前付き引数のみを受け入れます。位置呼び出しは受け入れません。多くの場合、発信者に最大限の柔軟性を与えたいので、ほとんどの回答が主張するように、2番目の形式が望ましいですが、常にそうであるとは限りません。通常は少数しか渡されない多くのオプションのパラメーターを受け入れる場合、名前付き引数の使用を強制することは優れたアイデアかもしれません(事故や呼び出しサイトでの読み取り不可能なコードを回避する!)-threading.Thread例です。最初の形式は、Python2でそれを実装する方法です。

このイディオムは非常に重要であるため、Python 3では特別なサポート構文があります。署名*内の単一の引数の後のすべての引数defはキーワードのみです。つまり、位置引数として渡すことはできず、名前付き引数としてのみ渡すことができます。したがって、Python 3では、上記を次のようにコーディングできます。

def f(*, foo=None, bar=None, **kwargs):
    ...etc...

実際、Python 3では、オプションではないキーワードのみの引数(デフォルト値のない引数)を持つこともできます。

ただし、Python 2にはまだ長い年月がかかるため、Python3の言語で直接サポートされている重要な設計アイデアをPython2に実装できるようにするテクニックとイディオムを忘れないでください。

于 2009-07-08T15:29:29.660 に答える
97

私はこのようなものを提案します

def testFunc( **kwargs ):
    options = {
            'option1' : 'default_value1',
            'option2' : 'default_value2',
            'option3' : 'default_value3', }

    options.update(kwargs)
    print options

testFunc( option1='new_value1', option3='new_value3' )
# {'option2': 'default_value2', 'option3': 'new_value3', 'option1': 'new_value1'}

testFunc( option2='new_value2' )
# {'option1': 'default_value1', 'option3': 'default_value3', 'option2': 'new_value2'}

そして、好きなように値を使用します

dictionaryA.update(dictionaryB)の内容を追加して、重複するキーdictionaryBを上書きします。dictionaryA

于 2009-07-08T15:03:14.037 に答える
61

あなたがするだろう

self.attribute = kwargs.pop('name', default_value)

また

self.attribute = kwargs.get('name', default_value)

を使用するpopと、偽の値が送信されているかどうかを確認し、適切なアクションを実行できます (存在する場合)。

于 2009-07-08T14:49:58.970 に答える
48

**kwargs とデフォルト値を使用するのは簡単です。ただし、そもそも **kwargs を使用してはならない場合もあります。

この場合、実際には **kwargs を最大限に活用していません。

class ExampleClass( object ):
    def __init__(self, **kwargs):
        self.val = kwargs.get('val',"default1")
        self.val2 = kwargs.get('val2',"default2")

上記は「なぜわざわざ?」です。宣言。と同じです

class ExampleClass( object ):
    def __init__(self, val="default1", val2="default2"):
        self.val = val
        self.val2 = val2

**kwargs を使用しているときは、キーワードが単なるオプションではなく、条件付きであることを意味します。単純なデフォルト値よりも複雑なルールがあります。

**kwargs を使用しているときは、通常、単純なデフォルトが適用されない次のようなことを意味します。

class ExampleClass( object ):
    def __init__(self, **kwargs):
        self.val = "default1"
        self.val2 = "default2"
        if "val" in kwargs:
            self.val = kwargs["val"]
            self.val2 = 2*self.val
        elif "val2" in kwargs:
            self.val2 = kwargs["val2"]
            self.val = self.val2 / 2
        else:
            raise TypeError( "must provide val= or val2= parameter values" )
于 2009-07-08T14:55:22.083 に答える
40

引数の数が不明な場合に使用されるので**kwargs、これを行うのはなぜですか?

class Exampleclass(object):
  def __init__(self, **kwargs):
    for k in kwargs.keys():
       if k in [acceptable_keys_list]:
          self.__setattr__(k, kwargs[k])
于 2012-11-29T15:55:28.550 に答える
16

**kwargsデフォルト値に関してPythonで使用する適切な方法は、以下に示すように辞書メソッドを使用することだと思いsetdefaultます:

class ExampleClass:
    def __init__(self, **kwargs):
        kwargs.setdefault('val', value1)
        kwargs.setdefault('val2', value2)

このように、ユーザーがキーワードで「val」または「val2」を渡すargsと、それらが使用されます。それ以外の場合は、設定されているデフォルト値が使用されます。

于 2013-04-02T16:39:14.967 に答える
16

別のアプローチを次に示します。

def my_func(arg1, arg2, arg3):
    ... so something ...

kwargs = {'arg1': 'Value One', 'arg2': 'Value Two', 'arg3': 'Value Three'}
# Now you can call the function with kwargs like this:

my_func(**kwargs)
于 2010-01-13T00:44:27.257 に答える
14

setattrを使用するという@srhegdeの提案をフォローアップします。

class ExampleClass(object):
    __acceptable_keys_list = ['foo', 'bar']

    def __init__(self, **kwargs):
        [self.__setattr__(key, kwargs.get(key)) for key in self.__acceptable_keys_list]

このバリアントは、クラスがリスト内のすべてのアイテムを持つことが期待される場合に役立ちacceptableます。

于 2016-03-31T14:34:37.153 に答える
13

あなたはこのようなことをすることができます

class ExampleClass:
    def __init__(self, **kwargs):
        arguments = {'val':1, 'val2':2}
        arguments.update(kwargs)
        self.val = arguments['val']
        self.val2 = arguments['val2']
于 2009-07-08T14:51:57.953 に答える
6

これを *args と組み合わせたい場合は、定義の最後に *args と **kwargs を保持する必要があります。

そう:

def method(foo, bar=None, *args, **kwargs):
    do_something_with(foo, bar)
    some_other_function(*args, **kwargs)
于 2012-09-19T09:50:37.387 に答える