** kwargs를 사용하여 ** kwargs 인수를 다른 함수에 전달


152

다음 예제를 이해하지 못하지만 이러한 기능이 있다고 가정 해 보겠습니다.

# python likes
def save(filename, data, **kwargs):
    fo = openX(filename, "w", **kwargs) # <- #1
    fo.write(data)
    fo.close()
# python doesnt like
def save2(filename, data, **kwargs):
    fo = openX(filename, "w", kwargs) # <- #2
    fo.write(data)
    fo.close()

def openX(filename, mode, **kwargs):
    #doing something fancy and returning a file object

# 1이 올바른 솔루션이고 # 2가 왜 잘못된 솔루션입니까? **kwargs기본적으로 dict이므로 openX에 인수를 전달하려면 올바른 방법이 없으면 **dict을 제공 하지 않을 것이라고 생각합니다 . 그러나 파이썬은 분명히 두 번째 것을 좋아하지 않으며 2 개의 인수 대신 3을주었습니다. 그렇다면 이것의 이유는 무엇입니까?

python 

5
**args코드에서 왜 그것을 호출하는지 궁금 합니다. 사람들이 그것을 혼동하기 때문에 이것은 아마도 최악의 이름 일 것입니다*args
John La Rooy

1
글쎄, 나는 * args를 절대 사용하지 않으므로 ** args ^^를 사용하지만 잘 수정할 수는 있습니다.

답변:


155

두 번째 예에서는 파일 이름, 모드 및 사전 ( kwargs) 이라는 세 가지 인수를 제공 합니다. 그러나 파이썬은 2 개의 형식 인수와 키워드 인수를 기대합니다.

사전에 '**'접두사를 붙여 사전 kwargs을 키워드 인수로 압축 해제합니다 .

사전 (type dict)은 키-값 쌍을 포함하는 단일 변수입니다.

"키워드 인수"는 키-값 방법 매개 변수입니다.

모든 사전은 **함수 호출 중에 접두사를 붙여 키워드 인수로 압축을 풀 수 있습니다 .


5
이제 알겠다. 키워드와 받아쓰기가 같은 것이라고 생각했습니다.

13
"함수 호출 중에 사전에 **를 접두어로 붙여 키워드로 확장 할 수 있습니다." <


8
실제 코드 예제는이 답변을 훨씬 명확하게 만듭니다.
OrangeDog

13

**구문은 파이썬에게 키워드 인수를 사전에 수집하도록 지시합니다. 는 save2비 키워드 인수 (사전 객체)로 아래로 전달합니다. 이 openX(가) 그래서 키워드 인수를보고하지 않는 **args사용되지 않습니다. 대신 키워드가 아닌 세 번째 인수 (사전)를 받고 있습니다. 이를 수정하여 openX함수 의 정의를 변경하십시오 .

def openX(filename, mode, kwargs):
    pass

고맙지 만 저장하지 않고 openX를 사용하고 싶습니다. 그래서 키워드를 고수해야합니다. 키워드를 전달하는 것이 기본적으로 dict을 전달하는 것과 동일하다고 생각했지만 지금까지 몰랐습니다. :)

@xMRW 사전을 매개 변수로 어떤 함수에도 전달할 수 있기 때문에 그것들은 같은 것이 될 수 없습니다. 당신의 # 1이 맞습니다.
Keith

8

@gecco의 답변을 확장하면 다음은 차이점을 보여주는 예입니다.

def foo(**kwargs):
    for entry in kwargs.items():
        print("Key: {}, value: {}".format(entry[0], entry[1]))

# call using normal keys:
foo(a=1, b=2, c=3)
# call using an unpacked dictionary:
foo(**{"a": 1, "b":2, "c":3})

# call using a dictionary fails because the function will think you are
# giving it a positional argument
foo({"a": 1, "b": 2, "c": 3})
# this yields the same error as any other positional argument
foo(3)
foo("string")

여기에서 사전 포장 풀기의 작동 방식과 실제 사전 전송이 실패하는 이유를 확인할 수 있습니다.


1

사전은 단일 값이므로 키워드 인수를 키워드 인수 그룹으로 전달하려면 키워드 확장을 사용해야합니다.


죄송하지만 "키워드 확장"이란 무엇입니까? ** args 대신 dict_var을 사용하고 def func (argument, dict_var = 0) ... func (1, {1 : "a", 2 : "b"})

1

# 2의 경우 인수는 dict 값을 가진 공식 매개 변수 일뿐 키워드 유형 매개 변수는 아닙니다.

키워드 유형 매개 변수를 키워드 인수에 전달하려면 사전 앞에 ** **를 지정해야합니다. ** args

** kw 사용에 대한 자세한 내용은 이것을 확인하십시오.

http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/


** kwargs와 dict 사이에는 큰 차이가 있습니까?

고맙습니다, 나는 항상 이해하지 못하는 주제에 대해 더 많이 읽고 싶습니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.