1. 함수 정의(def)
수학에서 함수(function)는 두 변수 x와 y에 대해서 x 값에 대해 하나의 y의 값이 결정될 때 이를 y는 x의 함수라고 부른다. 아래의 그림에서 입력값(input) x값이 들어오면 특정 함수에 x가 적용되어(f(x)) 최종 결과 값 y=f(x)를 반환(return)한다. 만약 함수 f(x) = x+2가 있다면 입력값 x=3을 넣으면 결과값 f(3) = 5를 반환한다.
파이썬에서 함수를 정의한다는 것은 어떤 값을 넣었을 때 2를 더해서 반환하는 f(x) = x + 2를 프로그래밍하는 것이다. 즉, 파이썬에서 함수는 입력값이 나오면 출력값을 가질 수 있도록 프로그램된 코드의 집합이라고 할 수 있다.
우리는 이미 많은 함수를 경험하였고 사용하였다. 입출력 문인 input(), print(), 길이나 개수를 세는 len(), count() 등은 모두 () 안에 입력값을 넣으면 출력값을 반환하는 함수들이다. len(A)라는 것은 A의 텍스트 길이를 계산하는 코드들이 len 이라는 함수명으로 이미 저장된 것이다.
파이썬에서 함수를 정의할 때 def 하는 명령어를 사용한다. 정의한다는 define의 앞 글자를 딴 것이다. 함수를 정의하는 형식은 다음가 같다. def 다음에 함수명을 만들고 ( ) 안에 투입될 입력값을 의미하는 매개변수를 삽입한다.
def 함수명(매개변수) :
<실행 명령문1>
<실행 명령문2>
<실행 명령문3>
...........
return <반환값>
함수명은 임으로 만드는 것이지만 간단하면서도 의미를 파악할 수 있는 소문자로 작성한다. 그리고 띄어쓰기는 허용하지 않고 대신 "_"를 사용해 함수명의 의미를 명료하게 만든다. 예를 들어 컵의 개수를 세는 함수라면 count_cups라고 정의하면 변수명만 보고도 대략 무슨 역할을 수행하는 함수인지 짐작할 수 있다.
함수를 생성할 때 함수가 호출하면 함수로 입력값을 전달하는 매개변수 또는 인자(arguments)와 함수가 완료되었을 때 반환하는 값(return)이 필요하다. 만약 두 수의 덧셈 함수를 만들면 x, y라는 값을 전달할 매개변수가 필요하고 두 값을 더한 x+y 가 반환 값이 된다.
2. 매개변수(전달 값) 전달 방식
함수를 정의할 때 ‘def 함수명(매개변수): ‘ 형식으로 작성하는 데 이때 매개변수를 함수 내 실행문으로 전달하는 다양한 방식이 존재한다.
1) 초기값 지정
매개변수를 함수 내 실행명령문으로 전달할 때 값을 고정할 수 있다. 예를 들어, pow(m, n)은 m, n을 매개변수로 m의 n 승을 계산하는 파이썬 내장함수이다. pow(2, 3) 하면, 2의 3승인 8이 반환 값이 된다. 매개변수인 m 또는 n을 고정할 수 있다. 마약 n=2로 고정하면 pow() 함수는 이제 어떤 수의 제곱승으로 계산한 함수로 그 역할이 바뀌게 된다.
def power(m=5, n=2): # 매개변수 초기값 3의 2승
return pow(m, n) # m=5로, n=2로 고정해 반환
print(power()) # 매개변수를 쓰지 않으면 초기값 5의 2승 반환
print(power(3)) # 매개변수를 하나만 지정하면 앞의 매개변수 m을 3으로 바꿈
print(power(4, 3)) # 매개변수를 둘다 기입하면 초기값이 사라지고 4의 3승을 계산
print(power(n=3)) # 매개변수의 뒤의 값을 가꾸기 위해서는 매개변수를 지정해 n을 3으로 바꿈
함수를 정의할 때 매개변수의 초기값을 지정하는 경우는 사람들의 리스트를 작성할 때 자주 사용된다. 예를 들어 학생 리스트를 작성할 때 모든 학생이 공통 요소인 ‘학교명’을 초기값으로 지정해 주면 ‘학교명’을 반복해서 입력할 필요가 없다. 예를 들어 ‘이름’, ‘학년’, ‘전공’, ‘학교’에 대한 정보를 담은 리스트를 만들 경우 ‘학교’는 모두 같기 때문에 초기값을 주고 나머지는 모두 유동적인 매개변수로 지정하면 된다. 만약 학교가 다른 사람이 있다면 추가로 학교를 넣어주면 된다.
def cilcles_list(name, age, major, school="한국대학교"):
print(f"이름 : {name}:\\t나이 : {age}\\t전공: {major}\\t 학교: {school}")
cilcles_list("홍길동", 29, "건축학") # 한국대학교 자동입력, 이름 : 홍길동: 나이 : 29 전공: 건축학 학교: 한국대학교
cilcles_list("성춘향", 18, "영화") # 한국대학교 자동입력, 이름 : 성춘향: 나이 : 18 전공: 영화 학교: 한국대학교
cilcles_list("이순신", 50, "전쟁", "지구대학교") # 지구대학교로 바꿔서 입력, 이름 : 이순신: 나이 : 50 전공: 전쟁 학교: 지구대학교
2) 매개변수 값 직접 지정
함수를 작성할 때 매개변수 지정 순서대로 입력값을 받게 된다. def grade(name, age, grade): 이렇게 함수를 정의했을 때 입력값을 name, age, grade 순서로 grade(”홍길동”, 20, “A”) 입력해야 한다. 하지만 매개변수가 너무 많거나 자료의 순서가 일관되지 않을 경우 순서대로 입력하기가 쉽지 않다. 이럴 경우 매개변수에 직접 전달 값을 입력하면 순서와 상관없이 매게변수에 맞게 함수 내 실형 명령문에 전달하게 된다.
def cilcles_list(name, age, major, school="한국대학교"):
print(f"이름 : {name}:\\t나이 : {age}\\t전공: {major}\\t 학교: {school}")
cilcles_list(major = "건축학", name="홍길동", age=29) # 순서가 섞여있어도 전달, 이름 : 홍길동: 나이 : 29 전공: 건축학 학교: 한국대학교
cilcles_list(age="20", major="영화", name="성춘향", school="한강대학교") # 순서와 디폴트 과목을 바꿈, 이름 : 성춘향: 나이 : 20 전공: 영화 학교: 한강대학교
3) 가변인자(*)
함수를 생성할 때 매개변수를 몇 개로 할지 알 수 없는 경우가 있다. 예를 들어 사용 가능한 프로그램 언어 개수가 사람마다 달라서 매개변수를 몇 개로 정할지 알 수가 없다. 이렇게 매개변수 개수를 결정할 수 없을 때 가변인자 *를 써서 매개변수를 만든다.
가변 인자가 없다면, 매개변수의 개수를 최대로 만들어야 한다. 사용 가능한 프로그램 수 최대치를 3개로 해서 prolang_1, prolang_2, prolang_3로 지정해 놓았는데 프로그램 언어를 4개 할 수 있는 사람이 추가된다면 다시 프로그램을 수정해야 한다. 가변인자 *를 써서 *prolang로 매개변수를 지정하면 전달 값 수만큼 자동으로 매개변수 개수를 지정해 실행문에 전달한다.
다음은 가변인자를 쓰지 않을 때 매개변수 지정과 가벼인자를 쓴 매개변수 지정과의 차이를 보여준다.가변인자를 쓰지 않을 경우 매개변수 수만큼 공백(””)을 넣어주어야 한다. 가변인자를 쓴 경우에는 하나의 매개변수 안에 여러 개의 값이 들어 있는 컨테이너 자료라고 생각하면 된다. 그래서 매개변수에 저장된 값을 for 문을 이용해 하나씩 가져오도록 함수를 정의한다.
# 가변인자를 쓰지 않은 경우
def prolang_list(name, age, prolang1, prolang2, prolang3):
print(name, age, hobby1, hobby2, hobby3, hobby4, hobby5)
prolang_list("홍길동", 29, "python", "C++", "JAVA")
prolang_list("이순신", 35, "python", "", "")
# 가변인자(*)를 사용
def prolang_list(name, age, *prolangs): # *prolangs: 가변인자
print(name, age, end=" ") # name과 age를 프린터하고 줄바꿈없이 다음을 프린트(end=" ")
for prolang in prolangs: # 매개변수에서 값을 하나씩 가져옴
print(prolang, end=" ")
print()
prolang_list("홍길동", 29, "python", "C++", "JAVA")
prolang_list("이순신", 35, "python")
3. 전역 변수와 지역 변수
함수를 정의하다 보면 함수 밖의 변수값을 받아와야 하는 경우와 함수 내에서 변수를 정의해야 하는 경우가 있다. 함수 밖에 있는 변수는 프로그램 전체에 영향을 미치는 변수로 전역변수라고 하고, 함수 내에서 정의된 변수는 함수 안에서만 영향을 미치기 때문에 지역변수라고 한다. 지역변수와 전역변수를 구분하지 못하면 논리에 맞지 않는 결과값을 반환한다.
아래 예에서 함수 밖의 전역변수 animals = 10이다. 그런데 함수 내에서 다시 지역변수 animals= 20으로 정의하였다.
# 총알로 동물을 맞춰서 남은 동물수 계산 함수
animals = 10 # 전역변수(함수 밖 변수)
def gun_shot(bullets):
animals = 20 # 지역변수(함수 내 변수)
animals = animals - bullets
return animals
함수를 정의하여 총알 2발을 쏠 경우 함수 내에서는 18마리의 동물이 남지만, 전체 동물 수를 확인해 보면 여전히 10마리라는 것을 확인할 수 있다.
# 함수 적용
gun_shot(2) # 함수를 적용한 결과는 18
# 전체 동물 수는 여전히 10
print(animals) # 전체 프로그램 결과 값은 바뀌지 않음: 10
1) 지역 변수를 전역 변수로 변환: global
함수 내의 지역 변수값이 함수 밖의 전역 변수값으로 치환되지 않기 때문에 함수 내의 지역변수를 전역 변수로 변환시킬 수 있다. 지역 변수 앞에 global을 붙여주면 이제부터는 지역 변수가 아니라 전역 변수로 취급한다. 그래서 함수가 실행되어서 반환된 값이 함수 밖에서도 바뀌게 된다.
# 총알로 동물을 맞춰서 남은 동물수 계산 함수
animals = 10 # 전역변수(함수 밖 변수)
def gun_shot(bullets):
global animals # 지역변수를 전역변수로 바꿈
animals = 20 # 지역변수(함수 내 변수)
animals = animals - bullets
return animals
지역변수를 global을 이용해 전역 변수를 바꾼 결과, 총알 2발을 쏜 함수의 결과 18마리의 동물이 남았고, 전체 동물 수도 18마리로 바뀌었다.
# 함수 적용
gun_shot(2) # 함수를 적용한 결과는 18
# 전체 동물 수는 여전히 10
print(animals) # 전체 프로그램 결과도 바뀜: 18
2) 전역 변수를 함수내 매개변수로 사용
지역 변수를 global을 이용해 전역 변수로 바꾸게 되면 코딩이 길어질 경우 전역변수와 지역변수 서로 혼동을 일으킨다. 그래서 지역변수를 전역 변수로 바꾸는 방법은 그다지 추천되지 않는다. 전역 변수와 함수 내 지역 변수 간 관계를 가장 잘 사용하는 방법은 전역 변수를 매개변수로 사용해 지역 변수를 없애는 방법이다.
위의 예제에서 bullets뿐만 아니라 animals도 함수의 매개변수에 넣게 된다. 그러면 함수 적용으로 인해 바뀐 리턴값이 저절로 함수 밖의 전역 변수값이 된다.
# 전역 변수를 함수의 매개변수로 사용
animals = 10 # 전역 변수(함수 밖 변수:)
def gun_shot(animals, bullets): # 전역 변수를 함수의 매개변수로 사용
animals = animals - bullets
return animals
전역 변수 10을 그대로 함수로 가져와 함수를 실행하면, 함수 적용 값과 최종 결과 모두 8이 된다.
gun_shot(animals, 2) # 함수를 적용한 결과는 8
# 전체 동물 수는 여전히 10
print(animals) # 전체 프로그램 결과도 8
'파이썬' 카테고리의 다른 글
[ 코랩과 파이썬 ] 13. python 필터 filter 함수 (isinstance 함수 포함) (0) | 2023.01.25 |
---|---|
[ 코랩과 파이썬 ] 12. python 람다 lambda 함수와 맵 map 함수 (0) | 2023.01.17 |
[ 코랩과 파이썬 ] 10. python 표준 입출력 input, print (0) | 2023.01.12 |
[ 코랩과 파이썬 ] 9. python 반복문 제어 break, continue, pass (2) | 2023.01.12 |
[ 코랩과 파이썬 ] 8. python 조건 반복문 while, else, 무한 반복 (0) | 2023.01.12 |