스터디/파이썬 스터디 강의자료

[4팀/김민혜] 5차시 파이썬 스터디 - 함수

알 수 없는 사용자 2023. 4. 13. 00:00

5차시_함수_해답.pdf
0.10MB
5차시_함수_강의안.pdf
0.48MB
5차시_함수_과제.pdf
0.23MB

1. 함수 - 기초


개념

DEF) 어떤 일을 수행하는 코드의 덩어리, 또는 코드의 묶음

  • 장점
    1. 필요할 때마다 호출이 가능하다
      • 반복적으로 수행해야 하는 업무를 한 번만 작성해 놓아도 됨
      • ⇒ 코드 수정 시 같은 작업을 여러 번 반복하지 않아도 된다는 점!
    2. 논리적인 단위로 분할이 가능하다
      • 간단히 도형을 계산하는 프로그램을 작성하더라도 곱셈 코드, 덧셈 코드, 나눗셈 코드 등으로 나눌 수 있음
    3. 코드의 캡슐화
      • 함수의 인터페이스만 잘 정의한다면 다른 사람이 쉽게 코드를 가져다 사용할 수 있음
        • 인터페이스의 정의 = 입력값(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를 곱한 값

  • 함수이름
    • 내용은 가능하면 짧게
    • 이름에 함수의 역할과 의도를 명확히
  • 역할
    • 하나의 함수에는 유사한 역할을 하는 코드만 포함
    • 최소한의 역할만 수행할 수 있도록 작성
  • 함수가 필요한 경우
    1. 공통으로 사용되는 코드를 함수로 변환
    2. 복잡한 로직이 사용되었을 때 식별 가능한 이름의 함수로 변환
      • 복잡한 조건이나 수식을 사용할 때
  • 실행순서
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