티스토리 뷰
[파이썬 입문 함수] def, global, lambda, iterator, yield @ 사용 방법
vicddory 2019. 8. 20. 08:00목차
함수 (def)
PYTHON - def 함수 문법 예제
def 문을 사용하여 함수(function)를 정의할 수 있습니다. 아래 파이썬 예제에서는 x, y라는 두 인수를 받아, 합계를 표시하는 함수 add()를 정의하고 호출합니다.
1 2 3 4 | def add(x, y): print x + y add(3, 5) #=> 8 | cs |
return은 함수의 반환값을 지정합니다. return 문을 생략하면 파이썬 함수는 None을 반환합니다.
1 2 3 4 5 6 | def add(x, y): ans = x + y return ans n = add(3, 5) print n #=> 8 | cs |
아래와 같이 키워드가 첨부된 인수를 지정할 수 있습니다. 키워드가 붙은 인수는 함수를 정의할 때 기본값을 지정할 수 있습니다.
1 2 3 4 5 6 | def repeat_msg(msg, repeat=3): for i in range(repeat): print msg repeat_msg('Hello') # Hello, Hello, Hello repeat_msg('Yahho', repeat=5) # Yahho, Yahho, Yahho, Yahho, Yahho | cs |
파이썬 팁
*name은 순서대로 인수를 받고, **name은 인수를 딕셔너리(Dictionary 사전) 형태로 받습니다.
1 2 3 4 5 6 7 | def func(a1, a2, *args, **params): print a1 #=> A print a2 #=> B print args #=> ('C', 'D') print params #=> {'k1': 'K1', 'k2': 'K2'} func('A', 'B', 'C', 'D', k1='K1', k2='K2') | cs |
args 및 params를 변수로 전달할 경우, 호출측에선 *와 **을 붙입니다.
1 2 3 | args = ('C', 'D') params = {'k1': 'K1', 'k2': 'K2'} func('A', 'B', *args, **params) #=> A, B, ('C', 'D'), {'k1': 'K1', 'k2': 'K2'} | cs |
함수는 여러값(복수)을 반환할 수 있습니다.
1 2 3 4 5 | def func(): return 3, "ABC" n, s = func() print n, s #=> 3 ABC | cs |
함수 정의의 시작 부분에는 """..."""를 이용해 함수를 설명하는 파이썬 문서를 작성할 수 있습니다.
1 2 3 | def func(x, y): """A sample function""" return x + y | cs |
전역변수(global)
PYTHON - global 함수 문법 예제
함수의 외부에 정의된 변수가 전역변수입니다. 함수에서 전역 변수를 참조할 순 있지만 할당할 순 없습니다. 대입할 경우에는 global로 선언해야 합니다.
1 2 3 4 5 6 | count = 0 # 글로벌 변수 def func(): print count # 참조할 수 있음 global count # global로 선언해 주면 count += 1 # 대입할 수 있음 | cs |
globals()는 전역변수, locals()는 로컬 변수 목록을 파이썬 딕셔너리로 반환합니다.
1 2 3 4 5 6 7 8 | def func(): for k in globals().keys(): print "GLOBAL: %s = %s" % (k, globals()[k]) for k in locals().keys(): print "LOCAL: %s = %s" % (k, locals()[k]) func() | cs |
람다식 (lambda)
PYTHON - 람다(lambda) 함수 문법 예제
람다 (lambda) 표현식은 이름 없는 작은 함수를 정의합니다. 람다식 자체는 식으로 취급되므로 함수의 인수로도 사용할 수 있습니다.
1 2 | myfunc = lambda x, y: x + y print myfunc(3, 5) #=> 8 | cs |
파이썬에서 lambda는 sorted(), map(), filter() 등의 함수에 전달하는 무명함수로 이용되기도 합니다.
1 2 | a = [1, 2, 3] print map(lambda x: x ** 2, a) #=> [1, 4, 9] | cs |
이터레이터 (iterator)
이터레이터는 for문에서 사용 가능한 반복 기능을 가진 객체입니다. 이터레이터 객체는 __iter__()로 next() 메소드를 가지는 객체를 반환하고 next() 메소드는 다음의 요소를 반환합니다. 마지막에 도달하면 StopIteration 예외를 반환합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class MyClass: def __init__(self): self.data = (1, 2, 3, 4, 5) self.index = 0 def __iter__(self): return self def next(self): if self.index < len(self.data): self.index += 1 return self.data[self.index - 1] else: raise StopIteration for n in MyClass(): print n #=> 1, 2, 3, 4, 5 | cs |
for문 마지막 작업은 아래와 똑같습니다.
1 2 3 4 5 6 7 8 9 | it = MyClass().__iter__() while 1: n = it.next() try: print n #=> 1, 2, 3, 4, 5 except StopIteration: break | cs |
제너레이터 (yield)
PYTHON - yield 함수 문법 예제
yield는 이터레이터를 반환하는 제너레이터를 정의할 때 사용됩니다. 우선 yield를 사용하지 않는 파이썬 예제를 살펴보겠습니다.
1 2 3 4 5 6 7 8 9 10 | def funcA(list): ret = [] for n in list: ret.append(n * 2) return ret for n in funcA([1, 2, 3, 4, 5]): print n #=> 2, 4, 6, 8, 10 | cs |
yield를 이용한 이터레이터 사용 방식으로 변경하면 아래와 같습니다.
실행 결과에는 변함이 없지만, funcA()가 [2, 4, 6, 8, 10]이란 리스트를 반환하는 반면 funcB()는 이터레이터 객체를 반환합니다.
이터레이터의 경우, 값이 참조될 때마다 다음 값이 계산되고 반환됩니다.
이 파이썬 예제에서는 5개 정도의 리스트이므로 퍼포먼스(성능) 차이는 없습니다.
그러나, list가 100만개라면 funcA() 함수를 호출한 시점에 100만개의 list가 생성되지만, 이터레이터의 funcB()의 경우 사용했을 때에만 다음 값을 계산하므로, 메모리 및 처리 효율이 개선됩니다.
1 2 3 4 5 6 | def funcB(list): for n in list: yield n * 2 for n in funcB([1, 2, 3, 4, 5]): print n #=> 2, 4, 6, 8, 10 | cs |
파이썬 예제를 좀 더 살펴보겠습니다. 아래는 파일을 읽고 __END__가 나타날 때까지 줄을 출력하는 프로그램 소스 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def readfileA(f): lines = [] for line in f: lines.append(line.rstrip()) return lines f = open("test.txt") for line in readfileA(f): if (line == "__END__"): break print line f.close() | cs |
yield를 활용한 이터레이터를 사용방법은 아래와 같습니다.
위의 파이썬 예제에선 파일을 모두 읽고 메모리로 로드하지만, 반복자를 사용한 예제에서는 한 줄(1행)의 메모리만 사용하여 __END__가 왔을 때 나머지를 건너뛰어 읽기 작업을 종료할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | def readfileB(f): for line in f: yield line.rstrip() f = open("test.txt") for line in readfileB(f): if (line == "__END__"): break print line f.close() | cs |
데코레이터 (@)
PYTHON - 데코레이터 @ 함수 문법 예제
함수를 실행 전과 후에 특수한 처리를 수행하려면 @ 데코레이터를 사용합니다. 아래 파이썬 예제에서는 hello() 함수를 mydecolater로 데코레이터(장식)합니다. 데코레이터 함수는 실행 전에 start, 함수 실행 후 end를 출력합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | def mydecolater(func): # 데코레이터 정의 def wrapper(): print "start" # 전처리 실행 func() # 데코레이터 대상 함수 실행 print "end" # 후처리 실행 return wrapper @mydecolater def hello(): print "hello" hello() #=> start, hello, end | cs |
아래는 데코레이터를 좀 더 범용적으로 사용한 예제입니다. 대상 함수에 @decolater로 설정함으로써, 함수의 인수나 반환값을 표시합니다. wraps()는 대상 함수의 함수 이름이나 문서 문자열(__doc__)을 유지하기 위해 호출합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | def mydecolater(func): import functools @functools.wraps(func) def wrapper(*args, **kwargs): print "Funcname:", func.__name__ print "Arguments:", args print "Keywords:", kwargs ret = func(*args, **kwargs) print "Return:", ret return ret return wrapper @mydecolater def func(msg1, msg2, flag=1, mode=2): """A sample function""" print "----", msg1, msg2, "----" return 1234 n = func("Hello", "Hello2", flag=1) print n print repr(func) print func.__doc__ | cs |
파이썬 입문 강좌 11강
- 자료형 문자열 각종 수식 정리
- 변수, 상수, 문서문자열(python docstring)
- 리스트 튜플 딕셔너리 (List, Tuple, dict)
- 제어문 - if else while for in break continue
- with assert pass del print exec 사용법
- 예외 처리 방식과 스택 추적 구현 방법
- 구문 - 문법, 주석, 들여쓰기, 인코딩 규칙
- 연산자 - 산술 비트 대입 비교 논리 조건
- def, global, lambda, iterator, yield @ 사용 방법
- 인스턴스, 메소드, 상속 등 예제 총정리
- 모듈 패키지 - 빌트인 파일 이름 사용 예제
관련 글
[파이썬 입문] 연산자 - 산술 비트 대입 비교 논리 조건
[파이썬 입문] with assert pass del print exec 사용법
[파이썬 입문] 제어문 - if else while for in break continue