[python] 파이썬에서 ** kwargs를 사용하는 올바른 방법

**kwargs파이썬이 기본값에 올 때 사용하는 적절한 방법은 무엇입니까 ?

kwargs사전을 반환하지만 기본값을 설정하는 가장 좋은 방법은 무엇입니까? 사전으로 액세스해야합니까? get 기능을 사용 하시겠습니까?

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

간단한 질문이지만 좋은 자료를 찾을 수없는 질문입니다. 사람들은 내가 본 코드에서 다른 방식으로 수행하며 사용 방법을 알기가 어렵습니다.



답변

get()사전에없는 키에 기본값을 전달할 수 있습니다 .

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

그러나 특정 기본값으로 특정 인수를 사용하려는 경우 먼저 명명 된 인수를 사용하지 않는 이유는 무엇입니까?

def __init__(self, val2="default value", **kwargs):


답변

대부분의 답변에서 예를 들어

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

와 같다”

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

이것은 사실이 아닙니다. 후자의 경우 f로 호출 할 수 있지만 f(23, 42)전자의 경우 에는 위치 호출이없는 명명 된 인수 허용 합니다. 발신자에게 최대의 유연성을 허용하려는 경우가 많으므로 대부분의 답변에서 주장하는 것처럼 두 번째 형식이 바람직합니다. 그러나 항상 그런 것은 아닙니다. 일반적으로 몇 개의 매개 변수 만 전달되는 많은 선택적 매개 변수를 허용하는 경우 명명 된 인수를 강제로 사용하는 것이 좋습니다 (예 : 호출 사이트에서 사고 및 읽을 수없는 코드 방지) threading.Thread. 첫 번째 형태는 파이썬 2에서 구현하는 방법입니다.

이 관용구는 파이썬 3에서 특별한 지원 구문을 갖 *습니다. def서명 에서 단일 뒤에 오는 모든 인수 는 키워드 전용입니다. 즉, 위치 인수로 전달 될 수없고 이름이 지정된 인수로만 전달 될 수 있습니다. 따라서 Python 3에서는 위와 같이 코드를 작성할 수 있습니다.

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

실제로 Python 3 에서는 선택 사항 이 아닌 키워드 전용 인수 (기본값 이없는 인수)를 가질 수도 있습니다 .

그러나 Python 2는 여전히 생산적인 수명이 길기 때문에 Python 3에서 언어로 직접 지원되는 중요한 디자인 아이디어를 Python 2에서 구현할 수있는 기술과 관용구를 잊지 않는 것이 좋습니다 !


답변

나는 이런 것을 제안한다

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)중복 키 dictionaryBdictionaryA덮어 쓰는 내용을 추가합니다 .


답변

당신은 할

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

또는

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

을 사용 pop하면 가짜 값이 전송되었는지 확인하고 적절한 조치를 취할 수 있습니다 (있는 경우).


답변

** 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" )


답변

**kwargs인수의 수를 알 수 없을 때 사용 되기 때문에 왜 이것을하지 않습니까?

class Exampleclass(object):
  def __init__(self, **kwargs):
    for k in kwargs.keys():
       if k in [acceptable_keys_list]:
          self.__setattr__(k, kwargs[k])


답변

다른 접근 방식이 있습니다.

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)