• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    해결됨

백엔드 데코레이터 2 강의에 도전 문제 질문드립니다

23.09.06 16:59 작성 조회수 142

0

가장 빠른 풀스택: 파이썬 백엔드와 웹기술 부트캠프 (flask/플라스크와 백엔드 기본) [풀스택 Part1] - 데코레이터 2

안녕하세요, 처음에는 데코레이터 파트는 넘기고 수강하다가, 수강하고 9개월이 지난 시점에 파이썬 중급을 공부하고 싶어 다시 찾아왔습니다 :)

도전 문제의 경우 아래와 같이 풀고 정답까지 잘 출력했습니다.

def mark_html(tag):
  def outer_wrapper(function):
      def inner_wrapper(*args, **kwargs):
        return f"<{tag}>{function(*args, **kwargs)}</{tag}>"
      return inner_wrapper
  return outer_wrapper

@mark_html('b')
def print_title(title):
  return title

print(print_title("안녕하세요"))

# 결과: <b>안녕하세요</b>

 

그런데 아주 살짝만 코드를 바꾸면 태그 안에 값이 None이 되더라고요

def mark_html(tag):
  def outer_wrapper(function):
      def inner_wrapper(*args, **kwargs):
        return print(f"<{tag}>{function(*args, **kwargs)}</{tag}>")
      return inner_wrapper
  return outer_wrapper

@mark_html('b')
def print_title(title):
  return print(title)

print_title("안녕하세요")

 

제가 생각하기에는

  1. print_title 함수가 mark_html 함수의 인자로 넘어가게 되면서 function에 print_title 함수가 들어가고 *args, **kwargs에 print_title의 title 파라미터가 들어가는 것으로 이해했습니다

  2. 따라서 데코레이터 안에 print(f"<tag>{function(*args, **kwargs)}<tag>")가 먼저 실행되고

  3. 이후에 print_title 함수가 실행되어 결과적으로는 <b>안녕하세요</b> \ 안녕하세요 가 출력될 것이라 예상하였습니다

  4. 하지만 막상 코랩과 스크립트 실행을 해보니 둘 다 안녕하세요 \ <b>None</b> 가 출력되더라고요

 

제 질문은 다음과 같습니다

  1. 실행 순서가 왜 뒤 바뀐 것일까요?

  2. <b> 태그 안에 값이 '안녕하세요'가 아닌 None으로 나오는 이유가 무엇일까요?

 

긴 질문 읽어주셔서 감사합니다

 

 

- 본 강의 영상 학습 관련 문의에 대해 답변을 드립니다. (어떤 챕터 몇분 몇초를 꼭 기재부탁드립니다)
- 이외의 문의등은 평생강의이므로 양해를 부탁드립니다
- 현업과 병행하는 관계로 주말/휴가 제외 최대한 3일내로 답변을 드리려 노력하고 있습니다
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

답변 1

답변을 작성해보세요.

0

안녕하세요 답변도우미입니다. 문의에 대해 정확히 이해한 것인지 조금 걱정이 되기도 하는데요. 최대한 답변드리겠습니다.

문제 1: 실행 순서가 왜 뒤 바뀐 것일까요?

이 부분은 파이썬의 print() 함수의 작동 방식 때문입니다. print() 함수는 출력을 즉시 수행하고, None을 반환합니다. 이렇게 되면, inner_wrapper에서 print()를 호출하면서 먼저 "안녕하세요"가 출력되고 나서, <b>None</b>가 출력되는 것입니다.

문제 2: <b> 태그 안에 값이 '안녕하세요'가 아닌 None으로 나오는 이유가 무엇일까요?

이 부분은 print_title 함수에서 print()를 사용했기 때문입니다. print() 함수는 None을 반환하므로, inner_wrapper에서 function(*args, **kwargs)를 호출하면 None이 반환됩니다. 그래서 <b>None</b>이 출력되는 것입니다.

여기서는 두 가지 방법으로 문제를 해결할 수 있습니다:

1. print_title 함수가 문자열을 반환하도록 수정합니다.

2. 또는 mark_htmlinner_wrapper에서 print()를 사용하지 않고 문자열을 반환하도록 수정합니다.

예를 들어 첫 번째 방법을 적용하면 아래와 같습니다.

def mark_html(tag):

  def outer_wrapper(function):

      def inner_wrapper(*args, **kwargs):

        return f"<{tag}>{function(*args, **kwargs)}</{tag}>"

      return inner_wrapper

  return outer_wrapper

@mark_html('b')

def print_title(title):

  return title  # print 대신 return 사용

print(print_title("안녕하세요"))

 

두 번째 방법을 적용하면 아래와 같습니다.

def mark_html(tag):

  def outer_wrapper(function):

      def inner_wrapper(*args, **kwargs):

        return f"<{tag}>{function(*args, **kwargs)}</{tag}>"

      return inner_wrapper

  return outer_wrapper

@mark_html('b')

def print_title(title):

  print(title)  # 그대로 print 사용

result = print_title("안녕하세요")  # 결과를 변수에 저장

print(result)  # 결과 출력

이렇게 하면 원하는대로 <b>안녕하세요</b>가 출력될 것입니다.

긴 설명이었지만 도움이 되었으면 좋겠습니다! 😊

김보겸님의 프로필

김보겸

질문자

2023.09.07

아 이해했습니다.

 

print() 함수의 특성상 즉시 인자에 들어온 것을 출력하고, None을 return하기 때문에

inner_wrapper 에서 function(*args, **kwargs)이 호출되어 print() 함수가 돌아가게 되면

  1. print() 안에 인자로 들어온 것을 출력

  2. function(*args, **kwargs)는 None 값을 반환

 

그렇기 때문에 순서도 바뀌고, <b>None</b> 이 나오는 것이었네요.

 

복잡한 내용인데, 자세하게 설명해주셔서 감사합니다 :)