정보
프로그램 원숭이 사려 깊은, 평생 학습 실무자, 신생 팀에서 현재 어떤 팀의 리더이며, 기술 스택은 안드로이드, 파이썬, 자바, Go를 포함, 이것은 주요 기술이 우리 팀을 스택입니다.
GitHub의 : https://github.com/hylinux1024
마이크로 채널 대중 번호 : 평생 개발자 (angrycode)
에서 Python
반복 가능한 ( Iterable
), 반복자 ( Iterator
)와 발전기 ( Generator
) 이러한 개념은 종종 사용되며, 이러한 몇 초보자가 알아 내기 위해 몇 가지 개념을 넣어 시간, 개념과 자주 혼동이다.
× 00의 반복 가능한 (의 Iterable)
단순히 긴 실현의 실현 한, (파이썬에서 모든 것은 객체) 객체를 넣어 __iter__()
하는 방법, 다음 isinstance()
검사의 함수 Iterable
객체;
예를 들면
class IterObj:
def __iter__(self):
# 这里简单地返回自身
# 但实际情况可能不会这么写
# 而是通过内置的可迭代对象来实现
# 下文的列子中将会展示
return self
클래스의 상기 정의 IterObj
및 구현은 __iter__()
이것이이다 방법을 반복 할 (의 Iterable) 개체
it = IterObj()
print(isinstance(it, Iterable)) # true
print(isinstance(it, Iterator)) # false
print(isinstance(it, Generator)) # false
이 클래스를 기억, 우리는이 클래스 정의 아래에 표시됩니다.
일반적인 반복 가능 객체
에 Python
공통되는 반복자는가?
- 설정 순서 또는 유형 (예를 들어
list
,tuple
,set
,dict
,str
) - File 객체
- 클래스의 정의
__iter__()
방법 개체로서 고려 될 수Iterable
있는 개체하지만 반복적 사용자 객체가 할 수 있도록for
정확한주기를 사용하여, 상기 확인하는 것이 필요하다__iter__()
구현 즉, 내장하여 (정확해야iter()
하는 기능 설정Iterator
객체. 대하여Iterator
이하 설명은 기억, 구덩이를 떠나 여기에있을 것입니다iter()
함수가 다음에하는 반복 가능한 반복자 객체로 전환 할 수있는 기능입니다for
) 사용
- 단지 클래스에서 구현되는 경우 달성
__getitem__()
개체 수iter()
자체가 반복의 객체를 반복자 함수로 변환하지만. 그래서 객체가 할 수있을 때for
사이클에서 실행하지만, 필요하지Iterable
객체.
약 1,2 점은 우리는 다음을 확인할 수 있습니다
print(isinstance([], Iterable)) # true list 是可迭代的
print(isinstance({}, Iterable)) # true 字典是可迭代的
print(isinstance((), Iterable)) # true 元组是可迭代的
print(isinstance(set(), Iterable)) # true set是可迭代的
print(isinstance('', Iterable)) # true 字符串是可迭代的
currPath = os.path.dirname(os.path.abspath(__file__))
with open(currPath+'/model.py') as file:
print(isinstance(file, Iterable)) # true
우리는 볼 점 3 ,
print(hasattr([], "__iter__")) # true
print(hasattr({}, "__iter__")) # true
print(hasattr((), "__iter__")) # true
print(hasattr('', "__iter__")) # true
이 내장 된 세트 또는 시퀀스 오브젝트가 __iter__
그들이 방법으로 같은 이름을 달성 한 속성을. 그러나이 반복 가능 객체가 할 for
다음은 내장해야한다, 사용주기에있을 iter()
함수 호출 및 변환 Iterator
객체.
예를 들어, 우리는 내장 된 반복 가능 객체보고
print(iter([])) # <list_iterator object at 0x110243f28>
print(iter({})) # <dict_keyiterator object at 0x110234408>
print(iter(())) # <tuple_iterator object at 0x110243f28>
print(iter('')) # <str_iterator object at 0x110243f28>
이들은 각각 해당 반복기 (로 전환된다 Iterator
) 개체.
이제 돌아가서의 정의의 시작 부분에 보면 IterObj
클래스
class IterObj:
def __iter__(self):
return self
it = IterObj()
print(iter(it))
우리는 사용 iter()
기능, 다음과 같은 정보가 밖으로이 시간 Jiangzai 콘솔 인쇄 :
Traceback (most recent call last):
File "/Users/mac/PycharmProjects/iterable_iterator_generator.py", line 71, in <module>
print(iter(it))
TypeError: iter() returned non-iterator of type 'IterObj'
오류의 유형을 의미 발생 iter()
함수 반복자 타입으로 '비 반복기를'전송 될 수 없다.
그럼 어떻게 하나의 반복 (수 있습니다 Iterable
반복자 (로) 객체 Iterator
) 객체?
우리는 수정거야 IterObj
클래스의 정의를
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
def __iter__(self):
return iter(self.a)
우리는에라는 이름의 생성자 정의 a
목록을, 또한 구현하는 __iter__()
방법을.
수정 된 클래스 수 iter()
즉 될 수 함수를 호출 for
사용주기
it = IterObj()
print(isinstance(it, Iterable)) # true
print(isinstance(it, Iterator)) # false
print(isinstance(it, Generator)) # false
print(iter(it)) # <list_iterator object at 0x102007278>
for i in it:
print(i) # 将打印3、5、7、11、13、17、19元素
따라서 반복자 오브젝트를 정의 할 때, 우리는에주의 __iter__()
개체 (예를 들면, 상기 한 세트의 시퀀스, 또는 다른 파일을 정확하게 정의 될 수있다 다수의 반복으로 알려져 있으며, 일반적으로 구현되는 내부 프로세스 로직 반복 가능한) 달성하기 위해 우리를 지원하기 위해
소개 포인트 (4)는 상술 한 것을 의미 iter()
기능이 달성 될 수 __getitem__()
있을 수있어서 반복자 객체로 변환 대상 for
사용주기하지만 만약 isinstance()
시간 검출 방법,이 반복자 객체 아니다.
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
def __getitem__(self, i):
return self.a[i]
it = IterObj()
print(isinstance(it, Iterable)) # false
print(isinstance(it, Iterator)) # false
print(isinstance(it, Generator)) false
print(hasattr(it, "__iter__")) # false
print(iter(it)) # <iterator object at 0x10b231278>
for i in it:
print(i) # 将打印出3、5、7、11、13、17、19
이 예는 캔 설명 에서 for
사용되는 객체, 그것은 반드시 반복 가능 객체가 아닙니다.
이제 우리는 요약합니다
- 반복 된 목적은 달성하는
__iter__()
오브젝트의 메소드 - 그것은 될 것입니다
for
그것은 충족해야 사용 사이클iter()
호출 (즉, 잘못되지 않습니다이 함수를 호출, 적절한로 설정할 수 있습니다Iterator
오브젝트) - 반복 가능 객체를 반복 가능한 알려져 우리의 사용자 정의를 달성하기 위해 도움을받을 수 있습니다.
- 개체는 구현
__getitem__()
방법이 될 수iter()
함수로 변환Iterator
될 수있는for
루프에서 사용하지만 반복자 객체 아니다 (isinstance 가능한 검출법 ())
반복자하는 0x01 (반복자)
많은 장소는 위에서 언급 한 Iterator
지금 우리는 구덩이를 다 채우실 필요.
우리는 반복자에 대한 반복의 개념을 이해하면 더 나은 이해된다.
객체 구현 __iter__()
및 __next__()
방법, 그것은 반복자 객체이다. 예를 들면
class IterObj:
def __init__(self):
self.a = [3, 5, 7, 11, 13, 17, 19]
self.n = len(self.a)
self.i = 0
def __iter__(self):
return iter(self.a)
def __next__(self):
while self.i < self.n:
v = self.a[self.i]
self.i += 1
return v
else:
self.i = 0
raise StopIteration()
에서 IterObj
목록, 생성자의 정의 a
,리스트의 길이 n
, 인덱스 i
.
it = IterObj()
print(isinstance(it, Iterable)) # true
print(isinstance(it, Iterator)) # true
print(isinstance(it, Generator)) # false
print(hasattr(it, "__iter__")) # true
print(hasattr(it, "__next__")) # true
우리는 상기 찾을 수 있습니다
컬렉션과 객체가 반복 순서가 아니라 반복자입니다
print(isinstance([], Iterator)) # false
print(isinstance({}, Iterator)) # false
print(isinstance((), Iterator)) # false
print(isinstance(set(), Iterator)) # false
print(isinstance('', Iterator)) # false
파일 객체는 반복자입니다
currPath = os.path.dirname(os.path.abspath(__file__))
with open(currPath+'/model.py') as file:
print(isinstance(file, Iterator)) # true
반복자 ( Iterator
) 객체는 수뿐만 아니라 for
주기, 내장의 기능도 할 수 있습니다 사용하는 next()
호출 기능. 예를 들면
it = IterObj()
next(it) # 3
next(it) # 5
0x02의 발전기 (제너레이터)
이제 빌더 무엇인지 살펴 보자?
발전기는 모두 반복적 인 반복자
생성기는 두 가지 방법을 정의한다 :
- 목록 작성기
- 하여
yield
함수 발생기의 정의
사례 1 봐
g = (x * 2 for x in range(10)) # 0~18的偶数生成器
print(isinstance(g, Iterable)) # true
print(isinstance(g, Iterator)) # true
print(isinstance(g, Generator)) # true
print(hasattr(g, "__iter__")) # true
print(hasattr(g, "__next__")) # true
print(next(g)) # 0
print(next(g)) # 2
데이터를 필요로 할 때 목록 작성기에만 계산됩니다 거대한 목록을 생성하기 위해 많은 메모리를 소비 할 필요가 있습니다.
사례 2 봐
def gen():
for i in range(10):
yield i
이 yield
효과는 동일하다 return
,이 함수의 차수가 반환 [0,10)
자연수로 제조 할 수 next()
또는 for
반복 루프.
프로그램이 발견 한 경우 yield
키워드를 다시 한 번 수행 할 때까지, 발전기 함수가 리턴, next()
기능, 그것은 즉, 마지막 실행 점 함수가 반환에서 계속 yield
기능 실행의 위치에 정보를 저장, 변수 등 출구에, 이것에 다시 실행될 때 yield
출구 장소를 계속합니다.
에서 Python
발전기의 이러한 기능을 활용하여 코 루틴 구현 될 수있다. 코 루틴 높은 동시성 시나리오의 처리에 대하여 그 스레드, 스레드 경량으로 이해 많은 장점이 될 수있다.
여기에 실현 코 루틴의 표정으로 생산자 - 소비자 모델
def producer(c):
n = 0
while n < 5:
n += 1
print('producer {}'.format(n))
r = c.send(n)
print('consumer return {}'.format(r))
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('consumer {} '.format(n))
r = 'ok'
if __name__ == '__main__':
c = consumer()
next(c) # 启动consumer
producer(c)
이 코드는 다음과 같은 효과를 수행
producer 1
consumer 1
producer return ok
producer 2
consumer 2
producer return ok
producer 3
consumer 3
producer return ok
코 루틴 달성 CPU
동시성을 달성하기 위해 두 가지 기능의 전환 효과.