본문으로 이동

프로그래머가 아닌 이들을 위한 파이썬 3 자습서/함수 정의하기

위키책, 위키책

함수 정의하기

[+/-]

이 장을 시작하기 전에 당신이 할 수는 있지만 할 필요는 없는 예제를 주겠다(그러니 타이핑 하지 마세요):

a = 23
b = -23

if a < 0:
    a = -a
if b < 0:
    b = -b
if a == b:
    print(a, "과", b, "의 절대값은", "같다.")
else:
    print(a, "과", b, "의 절대값은", "다르다.")

출력은 다음과 같다:

23 과 23 의 절대값은 같다.

프로그램이 조금 반복적으로 보인다. 프로그래머들은 반복되는 것들을 싫어한다 -- 결국 컴퓨터를 위한 것이다! (변수에 의해 바뀐 절대값을 찾았기 때문에 -23 대신 23이 출력된 것이다.) 다행히 파이썬은 중복을 제거하기 위한 함수를 만드는 것을 허용하고 있다. 아래는 재작성한 예제이다:

a = 23
b = -23

def absolute_value(n):
    if n < 0:
        n = -n
    return n

if absolute_value(a) == absolute_value(b):
    print(a, "과", b, "의 절대값은", "같다.")
else:
    print(a, "과", b, "의 절대값은", "다르다.")

출력은 다음과 같다:

23 과 -23 의 절대값은 같다.

이 프로그램의 주요 기능은 def 구문이다. def(정의(define)의 약어)는 함수의 정의를 시작한다. def 다음에는 함수의 이름absolute_value이 나온다. 그 다음에는 괄호 '()' 안에 매개변수 n (n은 함수가 호출될 때 프로그램에서 함수로 전달된다). ':' 다음에 오는 구문들은 함수가 사용될 때 실행될 것이다. 구문들은 들여쓰기된 구문이 종료되거나 return 구문이 발생하기 전까지 계속된다. return 구문은 함수가 호출된 곳으로 값을 반환한다. 우리는 우리의 첫 번째 프로그램에서 함수를 접해보았다 - print 함수 말이다. 이제 새로운 함수를 만들 수 있다.

어째서 ab 의 값이 바뀌지 않는 것인지 주목하여야 한다. 함수는 값을 반환하지 않으면서 반복되는 작업에 사용할 수 있다. 여기 여러 예제가 있다:

def hello():
    print("안녕하세요")

def area(width, height):
    return width * height

def print_welcome(name):
    print(name, "님, 환영합니다")

hello()
hello()

print_welcome("Fred")
w = 4
h = 5
print("가로 =", w, " 세로 =", h, " 넓이 =", area(w, h))

출력은 다음과 같다:

안녕하세요
안녕하세요
Fred 님 환영합니다
가로 = 4  세로 = 5  넓이 = 20

That example shows some more stuff that you can do with functions. Notice that you can use no arguments or two or more. Notice also when a function doesn't need to send back a value, a return is optional.

함수 속의 변수

[+/-]

반복되는 코드를 제거할 때, 반복되는 코드가 변수를 자주 가진다는 것을 볼 것이다. 파이썬에서는, 이러한 것들을 특별한 방법으로 처리한다. 여지껏 우리가 보아온 변수는 전역 변수(global variables)이다. 함수가 가지는 특별한 변수를 지역 변수(local variables)라고 한다. 지역 변수는 함수가 작동할 때에만 존재한다. 지역변수가 다른 변수(전역 변수라든지)와 동일한 이름을 가질 때에는, 지역 변수는 다른 변수를 숨긴다. 혼란스럽게 들리는가? 음, 다음 예제들은 (약간 인위적이지만) 이러한 개념을 명확히 해주는데 도움을 줄 것이다.

a = 4
 
def print_func():
    a = 17
    print("print_func에서 a = ", a)

print_func()
print("a = ", a)

실행시켰을 때, 우리가 얻을 수 있는 결과:

print_func에서 a = 17
a = 4

Variable assignments inside a function do not override global variables, they exist only inside the function. Even though a was assigned a new value inside the function, this newly assigned value was only relevant to print_func, when the function finishes running, and the a's values is printed again, we see the originally assigned values.

여기 좀 더 복잡한 다른 예제가 있다.

변수a = 10
변수b = 15
변수e = 25

def 예제함수(변수a):
    print("예제함수 속의  변수a = ", 변수a)
    변수b = 100 + 변수a
    변수d = 2 * 변수a
    print("예제함수 속의  변수b = ", 변수b)
    print("예제함수 속의  변수d = ", 변수d)
    print("예제함수 속의  변수e = ", 변수e)
    return 변수b + 10

변수c = 예제함수(변수b)

print("변수a = ", 변수a)
print("변수b = ", 변수b)
print("변수c = ", 변수c)
print("변수d = ", 변수d)

출력:

예제함수 속의  변수a =  15
예제함수 속의  변수b =  115
예제함수 속의  변수d =  30
예제함수 속의  변수e =  25
변수a =  10
변수b =  15
변수c =  125
Traceback (most recent call last):
 File "C:\def2.py", line 19, in <module>
   print("변수d = ", 변수d)
NameError: name '변수d' is not defined

이 예제에서 변수들 변수a, 변수b, 변수d예제함수 속에 있을 때에는 모두 지역 함수이다.. return 변수b + 10구문이 실행된 이후에, 그 변수들은 존재하지 않게 된다. 변수 변수a 는 매개변수의 이름으로 쓰인 때부터 자동적으로 지역변수가 된다. 변수 변수b변수d 는 함수 속 구문에서 등호의 왼쪽에 나타난 때(변수b = 100 + 변수a변수d = 2 * 변수a)부터 지역변수이다.

함수 내부에서 변수a 는 할당 값이 없다. 함수가 변수c = 예제함수(변수b)로 호출될 때, 그 당시 변수b의 값이 15였으므로, 함수의 호출은 예제함수(15)와 같기 때문에 그때부터, 15가 변수a에 할당된다. 이것으로 예제함수의 내부에서 변수a 의 값은 15로 설정된다.

당신이 보다시피, 한 번 함수가 종료하면, 같은 이름의 전역변수를 숨기던 지역변수 변수a변수b 는 사라진다. 그 다음 구문 print("변수a = ", 변수a)은 (전역변수를 숨기는) 지역변수가 사라졌기 때문에 15 대신 10 을 출력한다.

한가지 더 주의해야 할 사항은 끝에서 NameError가 나타난 것이다. 이것은 변수인 예제함수가 종료된 후 변수d가 더이상 존재하지 않기 때문에 나타난다. 모든 지역 변수는 함수가 종료하면 지워진다. 만약 당신이 함수에서 무언가를 얻길 원한다면, 당신은 return something을 사용하여야 한다.

마지막으로 주의해야 할 사항은변수e의 값은 예제함수 내부에서 값이 바뀌지 않은 채 유지된다는 것이다. 왜나하면 그것은 매개변수도 아니며 예제함수의 내부에서 등호의 왼쪽에 나타나지도 않았기 때문이다. 함수 내부에서 전역 변수가 사용된 때에는, 함수 외부의 전역 변수를 가져온 것이다.

함수는 오직 함수 내부에만 존재하고 함수 외부에 존재하는 다른 변수를 숨기는 지역 변수를 허용한다.

예제

[+/-]

temperature2.py

#! /usr/bin/python
#-*-coding: utf-8 -*-
# 화씨온도와 섭씨 온도를 변환합니다.
 
def print_options():
    print("옵션:")
    print(" 'p' 옵션을 출력합니다")
    print(" 'c' 섭씨 온도를 화씨 온도로 변환합니다")
    print(" 'f' 화씨 온도를 섭씨 온도로 변환합니다")
    print(" 'q' 프로그램을 종료합니다")
 
def celsius_to_fahrenheit(c_temp):
    return 9.0 / 5.0 * c_temp + 32
 
def fahrenheit_to_celsius(f_temp):
    return (f_temp - 32.0) * 5.0 / 9.0
 
choice = "p"
while choice != "q":
    if choice == "c":
        c_temp = float(input("섭씨 온도: "))
        print("화씨 온도:", celsius_to_fahrenheit(c_temp))
        choice = input("옵션: ")
    elif choice == "f":
        f_temp = float(input("화씨 온도: "))
        print("섭씨 온도:", fahrenheit_to_celsius(f_temp))
        choice = input("옵션: ")
    elif choice == "p": #다른 방법으로 != "q": 를 쓸 수도 있다.
                        #그러면 예상치 못한 입력에서도 옵션을 출력한다.
        print_options()
        choice = input("옵션: ")

실행의 예시:

옵션:
 'p' 옵션을 출력합니다
 'c' 섭씨 온도를 화씨 온도로 변환합니다
 'f' 화씨 온도를 섭씨 온도로 변환합니다
 'q' 프로그램을 종료합니다
옵션: c
섭씨 온도:  30 
화씨 온도: 86.0
옵션: f
화씨 온도:  60
섭씨 온도: 15.5555555556
옵션: q

area2.py

#! /usr/bin/python
#-*-coding: utf-8 -*-
# 직사각형의 넓이를 계산합니다.

def hello():
    print('안녕하세요!')
 
def area(width, height):
    return width * height
 
def print_welcome(name):
    print(name, "님 환영합니다.")
 
def positive_input(prompt):
    number = float(input(prompt))
    while number <= 0:
        print('반드시 양수가 입력되어야 합니다.')
        number = float(input(prompt))
    return number
 
name = input('당신의 이름은 무엇입니까: ')
hello()
print_welcome(name)
print()
print('직사각형의 넓이를 구하려면,')
print('너비와 높이를 입력해주세요.')
print()
w = positive_input('너비: ')
h = positive_input('높이: ')
 
print('너비 =', w, ' 높이 =', h, ' 그러므로 넓이 =', area(w, h))

실행 예시:

당신의 이름은 무엇입니까: Josh 안녕하세요! Josh 님 환영합니다.

직사각형의 넓이를 구하려면, 너비와 높이를 입력해주세요.

너비: -4 반드시 양수가 입력되어야 합니다. 너비: 4 높이: 3 너비 = 4.0 높이 = 3.0 그러므로 넓이 = 12.0

실습

[+/-]

위의 예제 area2.py에서 정사각형의 넓이와 직사각형의 넓이, 원의 넓이(3.14 * radius**2)를 구하는 함수를 구분하여 프로그램을 재작성하라. 이 프로그램은 메뉴 인터페이스를 가지고 있어야 한다.

틀:Solution

틀:Navigation 스크립트 오류: "TScope" 모듈이 없습니다.