goodthings4me.tistory.com
효율적 개발로 이끄는 파이썬 실천 기술 - 함수
(참고용으로 사용할 부분만 간략하게 정리)
함수
- 파이썬의 모든 데이터는 객체라고 함(클래스나 인스턴스, 함수도 객체)
- 함수를 정의하면 함수명의 이름과 똑같은 함수 객체(function object)가 만들어짐
- 함수 객체를 다른 함수의 인수(argument)로 전달하거나 변수에 대입 가능
- 함수명에 ()를 붙여 호출하고 처리(실행)한 결과를 반환값으로 호출자에게 반환
# 함수는 객체, function 타입
def print_page(content):
print(content)
print(print_page) # 함수 객체 출력 (함수명 print_page == 변수)
print_page('인수 있는 함수임') # ()를 붙여 호출, 인수 있음
print(print_page('no content')) # 파이썬의 함수는 return 문이 없어도 내부적으로 None 반환
print(type(print_page)) # function 타입
f = print_page # 함수 객체를 변수 f에 대입
f('인수 있는 함수')
# 다른 함수의 인수나 반환값으로 사용
def print_title(printer, title):
print('#' * 10)
printer(title.upper()) # printer는 함수 객체
print('#' * 10)
print_title(print_page, 'Python')
[결과]
<function print_page at 0x7f180e3ce830>
인수 있는 함수임
no content
None
<class 'function'>
인수 있는 함수
##########
PYTHON
##########
# 함수 인수에 기본값 지정
def increment(page_num, last=10):
next_page = page_num + 1
if next_page <= last:
return next_page
raise ValueError('Invalid argument')
try:
print(increment(8, 10))
print(increment(9))
print(increment(10, 12))
print(increment(10))
except ValueError as e:
print(f'에러: {e}')
[결과]
9
10
11
에러: Invalid argument
# 기본값의 함정
from datetime import datetime
def print_page(content, timestamp=datetime.now()):
print(content)
print(timestamp)
print(print_page('my content'))
print(print_page('my_content2'))
# 출력값이 동일한 이유 : 표현식이 함수가 정의될 때 한 번 값이 구해지고, 호출마다 같은 (미리 계산된) 값이 사용됨
[결과]
my content
2021-05-25 11:01:00.894542
None
my_content2
2021-05-25 11:01:00.894542
# 기본값에 현재 시각, 빈 리스트, 빈 딕셔너리 등의 가변객체를 지정하지 말고 None 사용하는 것이 좋음
from datetime import datetime
def print_page(content, timestamp=None):
if timestamp is None:
timestamp = datetime.now()
print(content)
print(timestamp)
print(print_page('my content'))
print(print_page('my_content2'))
[결과]
my content
2021-05-25 11:02:30.738843
None
my_content2
2021-05-25 11:02:30.746272
None
# 길이가 변하는 위치 및 키워드 인수
def print_page(*args, **kwargs):
for content in args:
print(content)
for key, value in kwargs.items():
print(f'{key}: {value}')
print_page('content1', 'content2', 'content3', published=2019, author='hey')
[결과]
content1
content2
content3
published: 2019
author: hey
# 인수 리스트 언팩 - 함수 호출 시 리스트나 딕셔너리의 값을 인수로 전달(리스트나 튜플은 * 연산자, 딕셔너리는 ** 연산자)
def ex_listunpack(one, two, three):
print(one)
print(two)
print(three, '\n')
contents = ['my content', 'content2', 'content3'] # 전달 인수의 개수 맞춤
ex_listunpack(*contents)
def ex_dictunpack(content, published, author):
print(content)
print(published)
print(author)
footer = {'published': 2019, 'author': 'hss'}
ex_dictunpack('my content', **footer)
[결과]
my content
content2
content3
my content
2019
hss
# lambda 식 - 1행의 이름 없는 함수 작성, 함수 인수로 함수 객체를 전달할 때 자주 사용
# 구문 lambda 인수1, 인수2, ...: 반환값이 되는 식
def increment(num):
return num + 1
# 위 함수를 lambda 식으로 하면
increment = lambda num: num + 1
print(increment)
print(increment(3))
# 내장 함수 filter()의 첫 인수로 lambda 함수 사용
nums = ['one', 'two', 'three', 'four']
filtered = filter(lambda x: len(x) == 3, nums)
print(filtered)
print(list(filtered))
[결과]
<function <lambda> at 0x7f180a975e60>
4
<filter object at 0x7f180a936690>
['one', 'two']
# 타입 힌트 : 정적타입언어와 같이 함수의 인수와 반환값에 타입 정보를 붙이는 기능이지만,
# 애너테이션 속성(annotations)에 저장될 뿐, 실행 시에 타입 체크 수행은 안함
def decrement(page_num: int) -> int: # 인수 및 반환값 타입 정보
prev_page: int # 타입 정보 붙여 변수 선언 가능
prev_page = page_num - 1
return prev_page
print(decrement(2))
print(decrement(2.0)) # 실행 시 타입 체크 안하기 때문에 에러 발생X
print(decrement.__annotations__) # 타입 정보 저장 확인
[결과]
1
1.0
{'page_num': <class 'int'>, 'return': <class 'int'>}
[참고/출처] 효율적 개발로 이끄는 파이썬 실천 기술 - 파이썬에 숨겨진 힘을 이용해 개발 효율을 높이자!
'코딩 연습 > 코딩배우기' 카테고리의 다른 글
파이썬 실천 기술 #05 - 이름공간, 스코프 (0) | 2021.06.03 |
---|---|
파이썬 실천 기술 #04 - 클래스와 인스턴스 (1) | 2021.05.26 |
파이썬 실천 기술 #02 - 데이터 구조 (0) | 2021.05.20 |
파이썬 실천 기술 #01 - PEP20, 제어흐름(if, for, while, Exception) (0) | 2021.05.18 |
파이썬 코딩의 기술 - 1.Pythonic #2 (0) | 2020.12.02 |
댓글