이 글은 Python에서 Yield 키워드의 사용법을 소개합니다(코드 예제). 필요한 친구들이 참고할 수 있기를 바랍니다.
yield는 Python의 키워드입니다. 처음 Python을 접했을 때 이 키워드에 대해 조금밖에 이해하지 못했는데, 익히고 나서 이 키워드가 매우 유용하다는 것을 깨달았습니다. . 이 글에서는 Yield를 사용하는 방법을 설명합니다.
1 Yield를 사용하여 생성기 만들기
Python에서 생성기는 반복 가능한 객체이지만 반복 가능한 객체가 반드시 생성기는 아닙니다.
예를 들어 리스트는 반복 가능한 객체입니다
>>> a = list(range(3)) >>> for i in a: print(i) 0 1 2 3
하지만 리스트 객체의 모든 값은 메모리에 저장됩니다. 데이터 양이 너무 많으면 메모리가 부족할 수 있습니다. 이 경우 생성기를 사용할 수 있습니다. 예를 들어 Python은 "()"를 사용하여 생성기 개체를 생성할 수 있습니다.
>>> b = (x for x in range(3)) >>> for i in b: print(i) 0 1 2 >>> for i in b: print(i) >>>
생성기는 반복될 수 있으며 데이터는 실제로 생성됩니다. 위의 실행 결과에서 볼 수 있듯이 두 번째 for 루프의 결과 출력은 비어 있습니다. .
실제 프로그래밍에서 함수가 직렬화된 데이터 조각을 생성해야 하는 경우 가장 간단한 방법은 모든 결과를 목록에 넣고 데이터 양이 많으면 반환하는 것입니다. 목록을 직접 반환하는 함수를 다시 작성하려면 Generator를 사용하는 것이 좋습니다(Effective Python, 항목 16).>>> def get_generator(): for i in range(3): print('gen ', i) yield i >>> c = get_generator() >>> c = get_generator() >>> for i in c: print(i) gen 0 0 gen 1 1 gen 2 2
for 루프를 사용하여 생성기가 반환한 값을 얻는 것 외에도 next를 사용하여 보낼 수도 있습니다
>>> c = get_generator() >>> print(next(c)) gen 0 0 >>> print(next(c)) gen 1 1 >>> print(next(c)) gen 2 2 >>> print(next(c)) Traceback (most recent call last): File "<pyshell#59>", line 1, in <module> print(next(c)) StopIteration
>>> c = get_generator() >>> c.send(None) gen 0 0 >>> c.send(None) gen 1 1 >>> c.send(None) gen 2 2 >>> c.send(None) Traceback (most recent call last): File "<pyshell#66>", line 1, in <module> c.send(None) StopIteration
생성기의 결과를 읽은 후 StopIteration 예외가 생성됩니다.# 🎜🎜#
2 코루틴에서yield를 사용하세요. 일반적인 사용 시나리오는 항복을 통해 코루틴을 구현하는 것입니다. 다음은 생산자입니다. 소비자 모델을 예로 들어보겠습니다:
# import logging # import contextlib # def foobar(): # logging.debug('Some debug data') # logging.error('Some error data') # logging.debug('More debug data') # @contextlib.contextmanager # def debug_logging(level): # logger = logging.getLogger() # old_level = logger.getEffectiveLevel() # logger.setLevel(level) # try: # yield # finally: # logger.setLevel(old_level) # with debug_logging(logging.DEBUG): # print('inside context') # foobar() # print('outside context') # foobar() def consumer(): r = 'yield' while True: print('[CONSUMER] r is %s...' % r) #当下边语句执行时,先执行yield r,然后consumer暂停,此时赋值运算还未进行 #等到producer调用send()时,send()的参数作为yield r表达式的值赋给等号左边 n = yield r #yield表达式可以接收send()发出的参数 if not n: return # 这里会raise一个StopIteration print('[CONSUMER] Consuming %s...' % n) r = '200 OK' def produce(c): c.send(None) n = 0 while n < 5: n = n + 1 print('[PRODUCER] Producing %s...' % n) r = c.send(n) #调用consumer生成器 print('[PRODUCER] Consumer return: %s' % r) c.send(None) c.close() c = consumer() produce(c)
[CONSUMER] r is yield... [PRODUCER] Producing 1... [CONSUMER] Consuming 1... [CONSUMER] r is 200 OK... [PRODUCER] Consumer return: 200 OK [PRODUCER] Producing 2... [CONSUMER] Consuming 2... [CONSUMER] r is 200 OK... [PRODUCER] Consumer return: 200 OK [PRODUCER] Producing 3... [CONSUMER] Consuming 3... [CONSUMER] r is 200 OK... [PRODUCER] Consumer return: 200 OK [PRODUCER] Producing 4... [CONSUMER] Consuming 4... [CONSUMER] r is 200 OK... [PRODUCER] Consumer return: 200 OK [PRODUCER] Producing 5... [CONSUMER] Consuming 5... [CONSUMER] r is 200 OK... [PRODUCER] Consumer return: 200 OK Traceback (most recent call last): File ".\foobar.py", line 51, in <module> produce(c) File ".\foobar.py", line 47, in produce c.send(None) StopIteration
n = yield r r = c.send(n)
import logging import contextlib def foobar(): logging.debug('Some debug data') logging.error('Some error data') logging.debug('More debug data') @contextlib.contextmanager def debug_logging(level): logger = logging.getLogger() old_level = logger.getEffectiveLevel() logger.setLevel(level) try: yield #这里表示with块中的语句 finally: logger.setLevel(old_level) with debug_logging(logging.DEBUG): print('inside context') foobar() print('outside context') foobar()
inside context DEBUG:root:Some debug data ERROR:root:Some error data DEBUG:root:More debug data outside context ERROR:root:Some error data
yield 일반적인 사용 시나리오는 전송 기능을 사용하여 코루틴을 구현하는 것입니다.
# 🎜🎜#yield는 contextmanager에 의해 수정된 함수의 with 블록에 있는 명령문을 나타낼 수도 있습니다.
위 내용은 Python에서 Yield 키워드 사용법 소개(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!