파이썬 tkinter button command Lambda 질문 드립니다.

조회수 3691회

파이썬 tkinter 사용중

button 위젯에 command를 통하여 함수를 실행하려 하였습니다.

하지만 정상적인 동작을 하지 않아서 질문 드립니다.

제가 사용한 코드는 다음과 같습니다.

TestBtn = Button(MainForm, text="확인", command= test01(10)) TestBtn.pack(side=LEFT, padx=10)

def test01(data): print("확인 테스트")

print(data)

위의 코드를 통해서 button을 클릭할 경우 "확인 테스트"와 10이라는 정보가 test01의 data에 담겨 정상적으로 출력 되는 것을 확인하고 싶었습니다.

하지만 첫 실행 후 바로 test(10)가 실행 되었지만 클릭을 할 경우에는 정상 동작하지 않았습니다.

다음은 수정한 코드 입니다.

TestBtn = Button(MainForm, text="확인", command= test01) TestBtn.pack(side=LEFT, padx=10)

def test01(data): print("확인 테스트")

print(data)

함수 이름만 사용하였으며 이 방법은 매개변수가 없는 함수를 실행 할 경우에 사용하면 정상 동작하는 형태입니다. 현재는 data라는 매개변수를 채우지 못하기 때문에

다음과 같은 오류가 발생하였습니다.

Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\ksh\AppData\Local\Programs\Python\Python37\lib\tkinter_init.py", line 1702, in __call_ return self.func(*args)

TypeError: test01() missing 1 required positional argument: 'data'

마지막으로 수정한 형태 입니다.

TestBtn = Button(MainForm, text="확인", command= lambda: test(10)) TestBtn.pack(side=LEFT, padx=10)

def test01(data): print("확인 테스트")

print(data)

다음과 같이 lambda를 추가하여 정상적으로 동작하는 것을 확인하였습니다. lambda를 사용하게 되면 매개변수에 정보가 담기고 button의 클릭도 정상적으로 동작하는 것을 확인 할 수 있었습니다.

제가 질문 드리고 싶은 것은

  1. 함수 이름만 사용하였을 때 동작하는 이유
  2. lambda를 사용할 경우 정상적으로 동작하는 이유가 궁금합니다.

좋은 답변 부탁드립니다.

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 제일 처음 코드가 안되는 이유는 test01이라는 함수가 실행하고 난 뒤의 리턴값을 command에 할당한 경우이기 때문입니다.

    파이썬에서 리턴값을 지정하지 않은 함수는 None을 리턴하므로 command = None 과 같은 의미죠.

    두 번째 시도는 옳았습니다. '클릭한 순간에 이 함수를 실행시켜라' 라는 의미로 command에는 실행 form이 아닌 함수 자체를 등록해야 합니다. 그런 의미에서 맞는 표현이긴 하죠. 다만 해당 표현은 말씀하신대로 파라메터를 넘길 수 없습니다.

    세 번째에 되는 것은 lambda: 라는 키워드로 선언된 부분이 이름없는 함수, 즉 익명함수를 의미하기 때문입니다. test함수에 매개변수 10을 넣어서 호출하는 함수를 만들어 넣어 준 것이죠.

    def a(data):
      print(data)
    
    def b():
      a(10)
    
    TestBtn = Button(MainForm, text="확인", command=b)
    

    와 거의 같은 의미라고 보시면 됩니다.

    lambda: 정도만 써도 괜찮지만, 이것을 좀 더 있어보이게...는 아니고 유연하고 함수형스럽게 쓰고 싶으면 functools의 partial 함수를 고려해 볼 수 있습니다.

    https://docs.python.org/2/library/functools.html#functools.partial

    특정 함수에 파라메터를 고정시킨 함수를 리턴하는 함수(?!?!) 이며 보통 currying 기법이라고도 불립니다.

    https://stackoverflow.com/questions/277922/python-argument-binders

    요런 식으로요.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)