- 목적
- 절차적 코드의 단점을 개선
- 특정 기능의 수행단위 구성
- 기능의 재사용성(활용) 높임
- 생산성 향상 -> 비용 감소 -> 기업/공익 이익
- 유지보수 유리
- 절차적 코드의 단점
- 중복 표현 많이 발생
- 기존 코드의 재사용 불가
- 흐름 제어의 난이도 높음 (코드가 복작함)
- 코드가 길어짐(확률이 높음)
- 장점
- 결론
- 함수 구성 본질
- 구성
- 입력
- 함수를 호출할때 데이터가 전달되는 통로
- 함수를 정의할때 : 매개변수, parameter
- 함수를 호출할때 : 인자, argument
- 생략 가능
- 처리/함수의 목적/비즈니스로직
- 예시
- 더하기 함수
- 로그인 처리 함수
- LLM이 프럼프트를 받아서 추론하여 결과를 응답하는 함수
- 영상 데이터를 받아서 이를 분석하여 판독/객체탐지/추적등을 수행
- ...
- 생략 가능 (함수의 의미 x)
- 출력
- 처리 결과를 반환
- 리턴값은 본질적으로 1개
- 만약 여러개라면 -> tuple(단순하게 값을 묶는다)로 반환됨
-
# [ ... ] => 생략 가능이라는 표식
# 함수 정의 기호
# 파이썬 def, JS function, 모바일 앱 func / fun
# 함수문법
[ 데커레이터 ] # fastapi와 같은 웹 구현시 자주 등장
def 함수명 ( [매개변수1, 매개변수2, ....] ):
# 들여쓰기(인텐트) 자동 삽입 -> 코드블럭을 구성함
# 처리파트 -> statements (수행문)
...
# 반환파트 -> 출력값이 없어도, 1개 ~ 여러개 OK
[return [출력값1, 출력값2, ..] ]
# 1. 함수 정의
# 가장 간단한 형태 -> 생략가능파트 전부 사용
def test():
pass
# 2. 함수 호출
# 함수는 호출해야 의미를 가짐
# 함수명( 필요시인자 )
test()
기본형
'''
요구사항
- 함수명 : add
- 입력 : 정수값 2개, x, y
- 처리 : 입력받은 두 값을 더하기 연산 처리(+)
- 출력 : 두 값의 합산값을 반환
'''
# 정의
def add(x, y): # 함수 정의, 입력 표현
res = x+y # 처리 -> 이 부분만 수정되면 내부 로직이 변경됨
return res # 반환, 출력 표현
# 사용
a = add(1,2)
a
# 이후 코드에서는 add() 함수를 더하기 기능이 필요할 때 사용 가능함
결과값 : 3
def add2(x, y):
print('->', x+y) # return 키워드 없음
print(add2(1,2))
# None => 반환값 없음!!(return 키워드 자체가 없거나 return만 존재하는 경우)
결과값 :
-> 3
None
# return만 사용하는 함수
def add3(x, y):
res = x + y
if res < 10:
print('10 미만 결과') # 1번 print
elif res > 20:
# return 단독 사용 -> 함수 처리 내용 중간에 바로 종료 처리 방식
return # 함수 종료 -> 반환값 없이 종료
print('함수 처리 완료') # 2번 print
add3(1,2) # 1,2번 찍힘
add3(11,2) # 2번만 찍힘
add3(111,2) # 중간에 return되어서 아무것도 안 찍힘
결과값 :
10 미만 결과
함수 처리 완료
함수 처리 완료
여러 개의 값 반환(튜플 타입으로 자동 처리됨)
'''
요구사항
- 함수명 : multi_operation
- 입력 : x, y
- 처리 : 입력받은 두 값에 대해 사칙연산 수행
- 출력 : 위의 연산 결과 4개를 반환
'''
# 함수 정의
def multi_operation(x, y):
res_add = x+y
res_sub = x-y
res_mul = x*y
res_div = x/y
return res_add, res_sub, res_mul, res_div
res_add, res_sub, res_mul, res_div = multi_operation(1,2)
res_add, res_sub, res_mul, res_div
결과값 : (3, -1, 2, 0.5)
- 함수에 데이터 전달 시 데이터 n개를 자유롭게 전달하고 싶다면 (1개 or 2개 or 3개, ..., n개)
- print()
print()
print(1)
print(1,2)
print(1,2,3)
print(1,2,3,4)
결과값 :
1
1 2
1 2 3
1 2 3 4
'''
요구사항
- 함수명 : add_ex
- 입력 : 가변인자 -> *인자명, 이름은 x를 사용
- 처리 : 입력된 가변인자를 모두 합산
- 반환 : 합산 결과
'''
def add_ex(*x):
print(x, type(x))
# 처리 -> 입력된 가변인자를 모두 합산
add_ex(1)
add_ex(1,2)
add_ex(1,2,3)
add_ex(1,2,3,4)
결과값 :
(1,) <class 'tuple'>
(1, 2) <class 'tuple'>
(1, 2, 3) <class 'tuple'>
(1, 2, 3, 4) <class 'tuple'>
def add_ex(*x):
res = 0 # 합산 값을 받을 변수
for n in x:
res += n
return res
print(add_ex(1))
print(add_ex(1,2))
print(add_ex(1,2,3))
print(add_ex(1,2,3,4))
결과값 :
1
3
6
10
- 배치 순서
- 일반 인자 -> 가변 인자 순으로 배치 (가변 인자가 앞에 오면 어디서부터 일반인자인지 알 수가 없음)
- 이런 경우 일반 인자는 필수(require) 인자로 인식
def add_ex2(x, *y):
print(f'x={x}, y={y}')
#add_ex2() : TypeError: add_ex2() missing 1 required positional argument: 'x'
add_ex2(1) # 비어있는 튜플로 가변인자가 처리됨, 절대 None은 나오지 않음
add_ex2(1,2)
결과값 :
x=1, y=()
x=1, y=(2,)
def add_ex3(*y, x):
print(f'x={x}, y={y}')
pass
add_ex3(1,2,3,4)
- 특징
- 변수의 타입을 가이드 -> 타입 확인
- 기본값 -> 가장 중요한 값 -> ML(머신러닝) 알고리즘에서 기본값
- 함수의 편의성 증가 -> 매개병수 생략 가능(기본값 적용)
- 매개변수는 필수가 아닌 옵션으로 변경됨
def feature_ext(stride=1, padding='same', shape=None):
print(stride, padding, shape)
# 호출
feature_ext() # 기본값이 있는 모든 인자는 옵션이 됨(missing 오류가 뜰 수가 없음)
feature_ext(2) # 2 -> stride에 들어감(순서대로 인자값 설정), 나머지 인자는 기본값으로 설정
feature_ext(3,'valid')
# 특정 인자만 세팅
feature_ext(padding='valid') # 나머지 인자는 기본값으로 설정, 지정된 인자는 세팅값으로 설정
# 매개변수의 순서를 제각각으로 세팅한다면
# 매개변수명(인자명) 지정해서 넣어주기만 하면 상관없음. 알아서 찾아감
feature_ext(shape = (2,2), stride = 2, padding = 'valid')
결과값 :
1 same None
2 same None
3 valid None
1 valid None
2 valid (2, 2)
keyword argument(kwargs) : 키워드 인자
- 표현
- **매개변수명
- 통상적으로 **kwargs 이렇게 씀
- 특징
- 함수의 가장 마지막 인자로 통상 위치됨
- 용도는 함수의 업그레이드 시 인자를 확장할 때 사용
- 기존 코드(올드 버전)는 그대로 유지, 새로운 인자가 들어오면 업그레이드로 처리함.(함수 내부에서)
def add4(**kwargs):
#키:값의 형태로 무한 확장 가능 -> 함수의 기능 확장
print(kwargs, type(kwargs)) # dict
add4()
# add4('hi', 3, 3.14) : 오류 발생, keyword -> dict의 key없이 사용함.
add4(msg= 'hi', rank = 3, pi = 3.14) # 매개변수명을 임의로 지정(실제로는 계획하고 사용)
결과값 :
{} <class 'dict'>
{'msg': 'hi', 'rank': 3, 'pi': 3.14} <class 'dict'>
종합 (일반인자, 가변인자, 키워드인자 등 조합)
def add5(x, y=1, *c, **kwargs):
print(x, y, c, kwargs)
add5(1,2,3,4,5,rank = 3, pi = 3.14)
# 질문 : x를 기본값 세팅하고 y를 안 하면 에러 왜?
# 기본값 세팅해도 인자 지정해서 넣는 것 된다
# 아래처럼 하면 가변인자에 값을 넣는 것은 불가능한지?
결과값 : 1 2 (3, 4, 5) {'rank': 3, 'pi': 3.14}
add5(pop = 'python', x = 100, y = 1000)
# 기본값이 없는 매개변수는 왼쪽처럼 넣어도 상관없음
# 순서대로 인자값 세팅할 것을 권장함
결과값 : 100 1000 () {'pop': 'python'}
- 목적
- 파이썬 프로그램과 파일(리소스) 사이의 통신을 위함
- 읽기, 쓰기, 생성, 열기, 닫기 기능 사용
- 기본은 텍스트 읽고쓰기, 바이너리 대상 가능
- 특징
- 파일은 s/w 외부에 존재함
- 로컬 PC, 클라우드 내 AWS S3 등에 존재할 수 있음
- I/O
- 잠재적으로 오류가 발생할 수 있음 -> 예외처리 필요
- 파일을 열었으면 반드시 닫아야 함(close)
# 기본 파일 생성 오픈 닫기
# 1. 오픈(없으면 생성하여 오픈)
f = open('a.txt', 'w')
# 2. 작업
f.write('ab AB 12 가나 !@')
# 3. 닫기
f.close()
# 코드가 길어지면 close()를 누락하는 경우가 종종 발생함 -> 언젠가는 파일이 열리지 않음
# 자동 close가 필요함 -> with문 -> I/O에서 자주 보임
# 별칭 부여 : as 별칭
with open('a.txt', 'w') as f:
f.write('ab AB 12 가나 !@')
# with문이 끝나면 자동 close()됨