iterable이란 파이썬에서 반복문을 사용할 수 있는 객체를 의미한다.
iter()에 인자 전달a=1
print(iter(a)) # iterable 하지 않음
a=1
for i in a: # 에러 발생
print(i)
a=[1,2,3]
print(iter(a)) # 출력 결과 <list_iterator object at 0x1047de6b0>
a=[1,2,3]
for i in a:
print(i)
출력결과
1
2
3
순회할 수 있는 객체를 의미. 파이썬에서 이터레이터는 iter()와 next() 메서드를 구현한 객체를 의미.
# 예제 코드
class MyIterator:
def __next__(self):
return 1
class MyIterable:
def __iter__(self):
obj=MyIterator()
return obj
m=MyIterable()
r=iter(m)
print(next(r))
print(next(r))
print(next(r))
class Season:
pass
s=Season()
for i in s:
print(i)
__iter__ method 구현class Season:
def __init__(self):
pass
def __iter__(self):
return self
s=Season()
for i in s:
print(i)
__next__ method 구현class Season:
def __init__(self):
self.data=["봄", "여름", "가을", "겨울"]
self.index=0
def __iter__(self):
return self
def __next__(self):
if self.index<len(self.data):
cur_season=self.data[self.index]
self.index+=1
return cur_season
else:
raise StopIteration
s=Season()
for i in s:
print(i)
map함수는 반복가능한 iterable 객체를 받아서, 각 요소에 함수를 적용하주는 함수
# 기존 코드
def add_1(n):
return n+1
target=[1,2,3,4,5]
result=[]
for value in target:
result.append(add_1(value))
print(result) # 결과 [2, 3, 4, 5, 6]
map함수를 이용하면 위와 같은 연산을 더 쉽게, 메모리도 절약할수 있는 iterator를 결규ㅏ를 받을수 있음.# map 함수 적용
def add_1(n):
return n+1
target=[1,2,3,4,5]
result=map(add_1, target)
print(list(result)) # 결과 [2, 3, 4, 5, 6]
# lambda 함수 적용
target=[1,2,3,4,5]
result=map(lambda x: x+1, target)
print(list(result)) # 결과 [2, 3, 4, 5, 6]
리스트 안의 값들을 str 타입으로 변환하는 예제
target=[1,2,3,4,5]
map(str, target)
filter함수는 특정 조건으로 걸러서 걸러진 요소들로 iterator 객체를 만들어서 리턴
# 기존 코드
target=[1,2,3,4,5,6,7,8,9,10]
result=[]
def is_even(n):
return True if n%2==0 else False
for value in target:
if is_even(value):
result.append(value)
print(result) # 결과 [2, 4, 6, 8, 10]
# filter() 적용
target=[1,2,3,4,5,6,7,8,9,10]
def is_even(n):
return True if n%2==0 else False
result=filter(is_even, target)
print(list(result)) # 결과 [2, 4, 6, 8, 10]
# lambda 적용
target=[1,2,3,4,5,6,7,8,9,10]
result=filter(lambda x: x%2==0, target)
print(list(result)) # 결과 [2, 4, 6, 8, 10]
이터레이터를 더 간단하게 구현할 수 있는 방법. 제너레이터는 함수 내에서 yield 키워드를 사용하여 값들을 하나씩 반환. 이터레이터와 마찬가지로 순회할 수 있는 객체를 반환.
# 예제 코드
def num_gen():
for i in range(3):
yield i
g=num_gen()
num1=next(g)
num2=next(g)
num3=next(g)
print(num1, num2, num3) # 결과 0 1 2
# for와 같이 사용
def num_gen():
for i in range(3):
yield i+1
g=num_gen()
for i in g:
print(i)
실행 결과
1
2
3
기존의 함수를 수정하지 않고, 그 함수에 기능을 추가하거나 수정하는 방법. 데코레이터는 함수나 메서드를 인수로 받아서 새로운 함수를 반환하는 함수.
# 예제 코드
def my_decorator(func):
def wrapper():
print('before func')
func()
print('after func')
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
출력 결과
before func
Hello!
after func
def hello():
print("hello")
>>> hello()
hello
def deco(fn):
def deco_hello():
print("*"*20)
fn()
print("*"*20)
return deco_hello
deco_hello=deco(hello)
hello() # 결과 hello
deco_hello()
********************
hello
********************
# @기호 사용하기
@deco
def hello2():
print("hello 2")
hello2()
********************
hello 2
********************
class Car:
def __init__(self, model):
self.model=model
@property
def get_model(self):
return self.model
c=Car("GV80")
print(c.get_model)
def outer(out1):
def inner(in1):
print("inner function called")
print("outer argument: ", out1)
print("inner argument: ", in1)
return inner
f=outer(1)
f(10)
def outer(out1):
def inner(in1):
print("inner function called")
print("inner argument: ", in1)
out1()
return inner
def hello():
print("hello")
f=outer(hello)
f(10)
def inner():
print("inner function called")
inner()
데코레이터와 Closure의 차이점은 외부 함수의 인자로 어떤 함수 객체를 입력받는다는 점.
def deco(f):
def wrapper():
print("-"*20)
f()
print("-"*20)
return wrapper
decorated_inner=deco(inner)
decorated_inner()
@deco
def inner():
print("inner function called")
inner()