찾다

 >  Q&A  >  본문

Python 协程的无限递归的问题

hi, 最近看了关于Python协程的相关文章协程的简单理解,说协程可以无限递归,于是想写一个协程示例练练,于是:

import time


def ping():
    print 'ping 0'
    count = 1
    try:
        pi,po = yield s
        print 'ping ' + str(count)
        count += 1     
        time.sleep(1)
        po.send([po, pi])
    except StopIteration:
        pass


def pong():
    print 'pong 0'
    count = 1
    try:
        po, pi = yield s
        print 'pong ' + str(count)
        count += 1
        time.sleep(1)
        pi.send([pi,po])
    except StopIteration:
        pass


s = ping()
r = pong()
s.next()
r.next()
s.send([s,r])

运行结果是:

ping 0
pong 0
ping 1
pong 1
Traceback (most recent call last):
  File "D:\test\coroutine.py", line 34, in <module>
    s.send([s,r])
  File "D:\test\coroutine.py", line 12, in ping
    po.send([po, pi])
  File "D:\test\coroutine.py", line 25, in pong
    pi.send([pi,po])
ValueError: generator already executing

那篇文章使用了stackless,我想实现一个原始的方法。但是出错,不知道要实现无限递归的话,应该怎么写嘞?

PHP中文网PHP中文网2802일 전864

모든 응답(4)나는 대답할 것이다

  • 天蓬老师

    天蓬老师2017-04-17 15:46:45

    코루틴을 관리하려면 실행 기능을 사용하는 것이 필요합니다.
    ping 및 pong 함수 내에서 Yield 반환이 실행됩니다.
    run 함수에서 next()를 사용하여 코루틴을 예약합니다.

    으아아아

    실행 결과:

    핑 0
    핑 0
    핑 1
    핑 1
    핑 2
    퐁 2
    핑 3
    퐁 3
    핑 4
    퐁 4
    …………

    ============================================= === =========
    메시지 버전 사용:

    으아아아

    실행 결과:

    ping 0
    pong 0
    ping 실행에서 메시지 가져오기
    ping 1
    pong ping에서 메시지 가져오기
    pong 1
    ping pong에서 메시지 가져오기
    ping 2
    퐁에서 메시지 받기 ping
    pong 2
    ping pong에서 메시지 가져오기
    ping 3
    pong ping에서 메시지 가져오기
    pong 3
    ping pong에서 메시지 가져오기
    ping 4
    .. ............

    회신하다
    0
  • PHP中文网

    PHP中文网2017-04-17 15:46:45

    작성하신 내용에 뭔가 문제가 있는 것은 사실이지만, 가장 중요한 점은 Stackless가 Python의 수정 버전이고, CPython에서 유사한 기능을 구현하려는 경우 코루틴이 표준 CPython의 코루틴과 다른 것 같습니다. , Greenlet을 기반으로 수행해야 할 수도 있습니다.

    회신하다
    0
  • 高洛峰

    高洛峰2017-04-17 15:46:45

    http://anandology.com/blog/using-iterators-and-generators/
    제너레이터 자체를 통과해서 문제가 발생한거고, 센드 자체로 인해 발생한 문제라고 해야되나
    pi po가 전역 변수라면 문제가 없을 겁니다

    회신하다
    0
  • 迷茫

    迷茫2017-04-17 15:46:45

    생성기의 사용이 명백히 잘못된 것입니다. s는 Yield에 의해 정지되지 않습니다. 물론 다시 send/next로 이동하면 이 오류가 보고됩니다
    구체적으로 무엇을 달성하고 싶은지 모르겠습니다. "탁구"를 번갈아 인쇄하려면 생성기를 사용하세요.

    회신하다
    0
  • 취소회신하다