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

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

# 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을주었습니다. 그렇다면 이것의 이유는 무엇입니까?



답변

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

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

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

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

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


답변

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

def openX(filename, mode, kwargs):
    pass


답변

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

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


답변

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


답변

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

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

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

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


답변