이번주는 Chapter8 Function에 대해서 조금 더 자세히 다뤄보고자 한다. 책에서는 없던 내용이지만 스스로 공부한 것 중에서 재귀함수와 지역·전역변수에 대해서 설명하겠다. 둘 다 들어는 봤을 것 같은 내용들이다. 그렇기 때문에 어려운 내용이 아니므로 천천히 그 의미와 사용법에 대해서 알아보자.

 

  • Recursive Function

 재귀함수란 자기 자신을 호출하는 것을 의미한다. 기본적으로는 함수 F를 만들면 다른 곳에서 F를 호출해 사용하지만 재귀함수는 F 함수 안에서 F 함수를 다시 호출하는 것으로 즉!!! 자기 자신을 다시 불러서 사용하는 것이다.
 보통 재귀함수를 공부해보면 제일 좋은 예시가 팩토리얼을 많이 이야기한다. 팩토리얼이란 n! 즉 n까지의 모든 정수를 모두 곱하는 것을 말한다. 이론적으로는 매우 쉽게 느껴지지만 코드를 실행해보면 '이게 왜 이렇게 되지??' 라는 의문을 가지는 게 재귀함수이다. 그러면 예제 코드를 먼저 살펴보고 사용법을 알아보자.

 

def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n-1)		# 재귀함수 호출

print(factorial(7))

결과
5040

 

 재귀 함수를 쓰는 방법은 간단하다. 자기 자신 이름을 호출하게 되면 그게 재귀 함수를 사용하는 방법이다. 위의 예제에서는 function 이름이 factorial이기 때문에 factorial()로 사용하고 있는 것을 알 수 있다. 그리고 재귀 함수로 들어간 함수는 끝에 도착했을 때 역으로 들어간 만큼 나오는 특징을 가지고 있다. 이 점을 유의하면서 공부해보자.
그러면 문제 : 위의 예제에서 factorial은 몇 번 실행됬을까??(정답을 알기 위해선 디버깅을 하는 게 가장 편하다.)
정답 : 7번(드래그하면 정답이 보입니다.)

 자! 그러면 정답이 왜 그렇게 되는지 그림으로 설명을 적어보겠다.

 

<factorial 재귀함수 순서>

 그림을 내가 직접 쓰면서 해서 이해가 조금 어려울 수도 있기 때문에 순서를 글로도 한 번 정리하겠다.

  1. 그림에서 1번 return과 2번 return이 존재한다. 하지만 1번 return은 n = 1일 때만 동작하기 때문에 무시하고 n = 7 ~ 2까지는 조건에 맞지 않아서 2번 return의 재귀 함수가 호출된다.

  2. n = 1일 때 드디어 1번의 retrun문이 실행되고 끝에 도착했기 때문에 재귀 함수로 들어온 수만큼 다시 돌아가게 된다.(return 값은 1을 가진 채로 돌아감)

  3. n = 2일 때로 돌아왔고 재귀 함수 위의 코드 즉 조건문은 실행을 하고 지나갔기 때문에 또 실행되지는 않고 재귀 함수 아래에 존재하는 코드(위의 예제에서는 없다. 존재한다면 재귀 함수 아래 코드로 진행)가 실행되고 n = 3으로 거슬러 올라간다.

  4. n = 3일 때는 2에서 올라온 retrun 값 2 * 1 = 2 를 가지고 3 * 2 = 6의 return 값을 가지고 4로 올라간다.

  5. 위의 행동을 7까지 반복한다.

  6. n = 7일 때 이때까지 누적되서 올라온 return 값과 (7 * 누적 값)을 return 값으로 가지고 function이 종료된다.

 

 디버깅을 하면 한 단계식 들어가는 것과 나가는 것을 볼 수 있으니 한 번 해보는 것을 추천한다.
(디버깅 방법을 모른다고 하시면 그것도 리뷰해드립니다. 말씀해주세요^^ / 디버그 실행 Ctrl+F9)

 

  • Global & Local Variable

 다음은 지역 변수와 전역 변수에 관한 이야기이다. 우리가 흔히 알고 있는 내용인데 함수 내에서만 사용하는 것을 지역 변수, 코드 전체에서 사용하는 것을 전역 변수로 지칭한다. 아래 예제를 살펴보고 전역변수와 지역변수의 차이점과 사용법을 알아보자.

 

x = 10 			 # 전역 변수
def foo1():
    x = 20 		 # x는 foo1의 지역 변수
    print(x) 		 # foo1의 지역 변수 출력
foo1()
print(x) 		 # 전역 변수 출력

def foo2():
    global x    	 # 전역 변수 x를 사용하겠다고 설정
    x = 20		 # x는 전역 변수
    print(x) 		 # 전역 변수 출력
foo2()
print(x) 		 # 전역 변수 출력

결과
20(global)
10(local)
20(global)
20(global)

 

 기본적으로 전역 변수는 함수 바깥에 선언한 모든 variable은 전역 변수로 사용된다. 그러므로 어디서 사용하던지 쓸 수 있고 반면에 지역 변수는 function 내에서 선언한 variable이기 때문에 바깥에서는 사용하거나 호출할 수 없게 된다. 
 전역 변수와 지역 변수가 이름이 같게 되면 지역에서 사투리를 먼저 쓰듯이 지역 변수가 우선으로 사용되고 만약에 전역 변수를 사용하고 싶으면 위의 예제처럼 global x(variable 명칭)를 통해 사용 할 수 있다.

 

 전역 변수와 지역 변수의 기본적인 사용법에 대해 알아보았다. 다음은 이중 함수 즉 지역 내의 지역이 있는 경우에 대해서도 알아보자. 보통 우리가 function을 쓸 때 특별한 기능을 쓰기 위해 사용하기도 하지만 한 개가 아닌 중첩 function을 사용해야 하는 경우도 있다. 그럴 때는 지역 변수 간의 차이와 용도를 아래 예제를 통해서 알아보자.

 

def A():
    x = 10              # function A 의 지역 변수
    y = 100             # function A 의 지역 변수
    def B():
        x = 20          # function B 의 지역 변수
        def C():
            """nonlocal : 상위의 지역 혹은 전역 변수 호출(계단형 검색)"""
            nonlocal x  # function A 의 지역 변수 호출
            nonlocal y  # function B 의 지역 변수 호출
            x = x + 30
            y = y + 300
            print(x)
            print(y)
        C()
    B()
A()

결과
50
400

 

 위의 예제코드를 그림으로 아주 쉽게 만들었다.(A 안에 B가 있고 B 안에 C가 있는 형태이다)

 

<nonlocal의 variable 찾는 방법>

 

 위와 같은 방법으로 지역이 중첩되어 있더라도 원하는 지역이나 전역의 variable을 가져다가 쓸 수 있다. 이번 장에서는 재귀 함수과 지역별 변수 사용 방법에 대해 알아보았다. 재귀 함수는 많이 쓰이지 않을 수도 있지만 전역 변수와 지역 변수 같은 경우에는 많은 코드를 짤 때 분명히 나눠야 되는 영역이기 때문에 꼭 학습하고 넘어가기로 하자.

'Python > No Starch Press_Python' 카테고리의 다른 글

Chapter10. Files and Exceptions  (0) 2020.05.20
Chapter9. Classes  (0) 2020.05.08
Chapter8. Functions  (0) 2020.04.28
Chapter7. USER INPUT AND WHILE LOOPS  (0) 2020.04.20
Chapter6. DICTIONARIES  (0) 2020.04.17
블로그 이미지

Mr.HB

프로그래밍 이야기

,