1. 함수 - 기초
개념
DEF) 어떤 일을 수행하는 코드의 덩어리, 또는 코드의 묶음
- 장점
- 필요할 때마다 호출이 가능하다
- 반복적으로 수행해야 하는 업무를 한 번만 작성해 놓아도 됨
- ⇒ 코드 수정 시 같은 작업을 여러 번 반복하지 않아도 된다는 점!
- 논리적인 단위로 분할이 가능하다
- 간단히 도형을 계산하는 프로그램을 작성하더라도 곱셈 코드, 덧셈 코드, 나눗셈 코드 등으로 나눌 수 있음
- 코드의 캡슐화
- 함수의 인터페이스만 잘 정의한다면 다른 사람이 쉽게 코드를 가져다 사용할 수 있음
- 인터페이스의 정의 = 입력값(input)과 출력값(output)을 명확히 하는 것
- 코드의 내부 구조를 몰라도 함수 사용 가능
- 함수의 인터페이스만 잘 정의한다면 다른 사람이 쉽게 코드를 가져다 사용할 수 있음
- 필요할 때마다 호출이 가능하다
함수 선언과 실행
def 함수이름 (매개변수 #1 ...):
명령문1
명령문2
return <반환값>
- 코드설명
- def: ‘definition’의 줄임말. 함수의 정의를 시작한다는 의미. 함수의 선언 부분은 코드의 처음에 입력해야 함.
- 함수이름: 변수를 지정하는 방식과 비슷하다
- 소문자 입력
- 띄어쓰기의 경우 ‘_’ 사용 ex) save_model
- 동사와 명사를 함께 사용하는 경우도 많음 ex) find_number
- 짧고 명료한 이름
- 매개변수(parameter): 함수에서 입력값으로 사용하는 변수. 1개 이상의 값을 적을 수 있음.
- 명령문: 반드시 들여쓰기 한 후 입력 필요. if나 for문 등의 제어문 사용 가능
- example
def calculate_rectangle_area(x,y)
return x*y
1) 함수이름: calculate_rectangle_area
2) 매개변수: x, y
3) return: 값을 반환 = x와 y를 곱한 값
- 함수이름
- 내용은 가능하면 짧게
- 이름에 함수의 역할과 의도를 명확히
- 역할
- 하나의 함수에는 유사한 역할을 하는 코드만 포함
- 최소한의 역할만 수행할 수 있도록 작성
- 함수가 필요한 경우
- 공통으로 사용되는 코드를 함수로 변환
- 복잡한 로직이 사용되었을 때 식별 가능한 이름의 함수로 변환
- 복잡한 조건이나 수식을 사용할 때
- 실행순서
def calculate_rectangle_area(x,y)
return x*y
rectangle_x = 10
rectangle_y = 20
print("사각형 x의 길이:", rectangle_x)
print("사각형 y의 길이:", rectangle_y)
#넓이를 구하는 함수 호출
print("사각형의 넓이:", calculate_rectangle_area(rectangle_x, rectangle_y))
<코드 설명>
1. 먼저 함수가 정의된 def 부분은 실행X. 별도의 출력이 일어나지 않음.
2. 함수가 수행해야 하는 명령의 실행. 위에서부터 차례대로 print문을 수행한 뒤, return x*y에 의해 반환값 200이 반환됨.
3. calculate_rectangle_area(rectangle_x, rectangle_y)이 200으로 치환되고, 이를 화면에 출력함.
용어
- 매개변수(parameter)
: 위 코드에서 괄호 안에 들어있는 x, y 등
- 함수의 인터페이스 정의에 있어 어떤 변수를 사용하는지 정의하는 것
- 인수(argument)
: 실제 변수에 대입되는 값
➕ 실제로 매개변수와 인수는 구분 없이 사용하는 경우가 많고, 모두 함수의 입력값으로 부르기도 함
함수의 형태
매개변수 X | 매개변수 O | |
반환값 X | 함수 내부 명령문만 수행 | 매개변수를 사용해 명령문만 수행 |
반환값 O | 매개변수 없이 명령문 수행 후, 결과값 반환 | 매개변수를 사용해 명령문을 수행 후, 결과값 반환 |
#case1
def a_rectangle_area(): #매개변수x, 반환값x
print(5 * 7)
a_rectangle_area()
#case2
def b_rectangle_area(x,y): #매개변수o, 반환값x
print(5 * 7)
b_rectangle_area(5,7)
#case3
def c_rectangle_area(): #매개변수x, 반환값o
return(5 * 7)
print(c_rectangle_area())
#case4
def d_rectangle_area(x,y): #매개변수o, 반환값o
return(5 * 7)
print(d_rectangle_area(5,7))
- case1
- 입력값, 반환값 모두 X
- print(5*7)로 인해 35 출력
- a_rectangle_area()는 반환값이 없으므로 함수 자체의 값은 none
- case2
- 매개변수가 존재하나 반환값은 X
- b_rectangle_area(5, 7) 자체가 35로 치환되는 것은 아님!
- 반환이 없다면 해당 함수는 none으로 치환
- case3, case4
- 반환값이 있음
- 두 함수 모두 return문으로 인해 35로 치환됨
- 함수의 반환값이 있는 경우, 함수를 호출하는 곳에서 함수의 반환값을 변수에 할당하여 사용하는 것이 가능
2. 함수 - 심화
호출방식
def f(x):
y=x
x=5
return y*y
x=3
print(f(x))
print(x)
- 값에 의한 호출 call by value
- 함수에 인수를 넘길 때 값만 넘김
- 함수 내부의 인수값 변경 시 호출된 변수에 영향 X
- 참조 호출 call by reference
- 함수에 인수를 넘길 때 메모리 주소를 넘김
- 변수가 저장되는 공간 자체에 새로운 값을 할당하면 그 공간을 가리키고 있는 다른 변수에도 영향을 줌
- 함수 내부의 인수값 변경 시 호출된 변수값도 변경
- 함수에 인수를 넘길 때 메모리 주소를 넘김
파이썬: 객체 호출 call by object reference
- 객체의 주소를 함수로 넘기기 때문에 전달된 객체에 1) 새로운 값을 할당하거나 2) 해당 객체를 지울 때는 영향을 주지 않음
- But, 단순히 해당 객체에 값을 추가할 때는 영향을 줌
def spam(eggs):
eggs.append(1) #기존 객체의 주소값에 [1] 추가
eggs = [2,3] #새로운 객체 생성
ham = [0]
spam(ham)
print(ham)
- 먼저 ham이라는 리스트를 만들고, 함수 spam에 ham을 인수로 입력
- 함수 안에서 이름은 eggs (이때, ham과 eggs는 객체 호출 방식에 의해 같은 주소를 공유)
- eggs.append(1)에서는 ham, eggs 모두 영향을 받음
- eggs=[2,3]을 통해 더 이상 ham과 eggs는 같은 메모리 주소를 가리키지 않음
- 그리고 함수를 빠져나와 print(ham) 실행시 추가된 [0,1]을 출력
- 새로운 값을 할당하기 전까지는 기존에 넘어온 인수 객체의 주소값을 그대로 사용하는 방식
변수 사용범위 scoping rule
DEF) 변수가 코드에서 사용되는 범위
- 함수 내부에서 사용할 것인지, 프로그램 전체에서 사용할 것인지 결정하는 것
def test(t):
print(x)
t=20 #지역변수
print("In Function:", t)
x=10 #전역변수
test(x)
print("In Main:", x)
print("In Main:", t)
*실행했을 경우 print(”In Main:”, t)는 오류 출력. (변수 t는 함수 내부에서만 사용할 수 있는 지역 변수.)
- 고려해야 할 변수
- 지역 변수 local variable: 함수 내부에서만 사용
- 전역 변수 global variable: 프로그램 전체에서 사용
- 함수 내부와 외부의 변수가 같은 메모리 주소를 갖도록 함
- global 키워드로 선언
def f():
global s
s = "I love London!"
print(s)
s="I love Paris!"
f()
print(s)
- 예시 - 출력 결과를 예측해봅시다
#Example1
def f():
s="I love London!"
print(s)
s="I love Paris!"
f()
print(s)
- 함수 내부와 외부에 있는 변수 s는 이름이 같지만 다른 메모리 주소를 갖고 있는 전혀 다른 변수
- 함수 내부의 s는 해당 함수가 실행되는 동안에만 메모리에 있다가 함수가 종료되면 사라짐.
#Example2
def calculate(x,y):
total=x+y #새로운 값 할당으로 함수 내부 total은 지역 변수
print("In Function")
print("a:",str(a),"b:",str(b),"a+b:",str(a+b),"total:",str(total))
return total
a=5 #a,b는 전역 변수
b=7
total=0 #전역 변수 total
print("In Program-1")
print("a:",str(a),"b:",str(b),"a+b:",str(a+b))
sum=calculate(a,b)
print("After Calculation")
print("Total:", str(total), "Sum:", str(sum)) #지역 변수는 전역 변수에 영향 주지 않음
#출력결과
In Program-1
a:5 b:7 a+b:12 total:12
After Calculation
Total:0 Sum:12
재귀함수 recursive function
DEF) 자기 자신을 다시 호출하는 함수
- 자신을 이용해 다른 것을 정의한다는 의미
- 예) 점화식_팩토리얼factorial 함수
def factorial(n):
if n==1:
return 1
else:
return n * factorial(n-1)
print(factorial(int(input("Input Number for Factorial Calculation: "))))
#출력결과
Input Number for Factorial Calculation: 5
120
- 기본 구조가 종료 조건, 단계별 반환으로 구성되어 있으므로 크게 변경 없이도 사용할 수 있음
3. 인수 argument
인수 사용법
종류 내용
종류 | 내용 |
키워드 인수 | 함수의 인터페이스에서 지정한 변수명을 사용해 함수의 인수를 지정하는 방법 |
디폴트 인수 | 별도의 인수값이 입력되지 않을 때 인터페이스 선언에서 지정한 초깃값을 사용하는 방법 |
가변 인수 | 함수의 인터페이스에서 지정한 변수 이외의 추가 변수를 함수에 입력할 수 있도록 지원하는 방법 |
키워드 가변 인수 | 매개변수의 이름을 따로 지정하지 않고 입력하는 방법 |
키워드 인수 keyword arguments
DEF) 함수에 입력되는 매개변수의 변수명을 사용해 함수의 인수를 지정하는 방법
def print_something(my_name, your_name):
print("hello {0}, my name is {1}".format(your_name, my_name))
print_something("Sungchul", "TEAMLAB")
print_something(your_name="TEAMLAB", my_name="Sungchul")
*출력 결과는 동일
- 입력되는 순서에 상관없이 함수의 입력 변수명만 정확히 기재된다면, 원하는 변수에 인수를 넣을 수 있음
디폴트 인수 default arguments
DEF) 매개변수에 기본값을 지정하여 사용하고, 아무 값도 인수로 넘어가지 않을 때 지정된 기본값을 사용하는 방식
def print_something_2(my_name, your_name="TEAMLAB"):
print("hello {0}, my name is {1}".format(your_name, my_name))
print_something_2("Sungchul", "TEAMLAB")
print_something_2("Sungchul")
*출력 결과는 동일
- your_name 매개변수에 기본값으로 ‘TEAMLAB’이 지정됨
- 별도의 값을 할당하지 않아도 작동
가변 인수 variable-length arguments
DEF) 매개변수를 정하지 않고 사용하는 방식
➕ 예
- 항의 개수가 정해지지 않은 다항방정식의 덧셈 연산
- 마트 계산기에서 합산을 수행하는 연산
- *(asterisk)로 표현
- 곱셈 또는 제곱 연산 외에도 변수를 묶어주는 가변 인수를 만들 때 사용
def asterisk_test(a,b,*args):
return a+b+sum(args)
print(asterisk_test(1,2,3,4,5))
15 #실행결과
*변수 a, b를 넘겨받고 나머지를 *args로 넘겨받음
- *args = 가변 인수
- 출력 시, 괄호로 묶여 출력되는 튜플tuple 자료형임
- 변수의 이름을 지정할 수 없다는 단점
- 반드시 일반적인 키워드 인수에 대한 선언이 모두 끝난 후 마지막에 선언되어야 함
def asterisk_test_2(*args):
x,y,*z=args
return x,y,z
print(asterisk_test_2(3,4,5,10,20))
(3,4,[5,10,20]) #실행결과
- 언패킹과 동일한 개념이므로 언패킹 개수 또한 맞춰야 함
키워드 가변 인수 keyword variable-length arguments
DEF) 매개변수의 이름을 따로 지정하지 않고 입력하는 방법
- *를 2개 사용, 변수명 kwargs
- 딕셔너리 자료형dictionary type으로 사용
- 변수명과 값을 쌍으로 저장하는 방식
- 모든 매개변수의 맨 마지막, 즉 가변 인수 다음에 선언
def kwargs_test(**kwargs):
print(kwargs)
print("First value is {first}".format(**kwargs))
print("Second value is {second}".format(**kwargs))
print("Third value is {third}".format(**kwargs))
kwargs_test(first=3, second=4, third=5)
#출력결과
{'first':3, 'second':4, 'third':5}
Fist value is 3
Second value is 4
Third value is 5
'스터디 > 파이썬 스터디 강의자료' 카테고리의 다른 글
[4팀/김민혜] 6차시 파이썬 스터디 - 문자열 (0) | 2023.04.28 |
---|---|
[4팀/이제은] 6차시 파이썬 스터디 - 문자열 (0) | 2023.04.28 |
[1팀/허서원] 5차시 파이썬 스터디 - 함수 (0) | 2023.04.06 |
[4팀/이제은] 5차시 파이썬 스터디 - 함수 (0) | 2023.04.06 |
[1팀/지다인] 5차시 파이썬 스터디 - 함수 (0) | 2023.04.06 |