我有这段代码,但我不明白为什么 print(su) 的结果不为零

I have this code and I don't get why the result of print(su) isn't zero

帮我理解为什么 yield total 在第一次调用时不显示为 0

自从 [sumer] 通过 @coroutine 通过 [primer], [su] 已经在 primer 的旁边遇到过 next() 对吧?

所以我猜 print('EX2-1 -',su) 的结果 应该 0

但是真正的结果竟然只是显示了su的地址, 只有在 su.send(100) 之后,该值才会显示为 100

我错过了什么??

from functools import wraps
from inspect import getgeneratorstate


def coroutine(func):
   @wraps(func) 
   def primer(*args, **kwargs):
       gen = func()
       next(gen)
       return gen
   return primer

@coroutine
def sumer():
    total = 0
    term = 0
    while True :
        term = yield total
        print('term recieved')
        total += term

su = sumer()
print('EX2-1 -',su)
print(getgeneratorstate(su))
print('EX2-1 -', su.send(100))

su 是生成器对象本身。如果你想在任何时候获得 total 的当前值,你需要让它产生它,但你不能使用 next() 因为这会使 term 成为 None 这将导致错误。相反,您需要使用 .send(0):

from functools import wraps
from inspect import getgeneratorstate


def coroutine(func):
   @wraps(func) 
   def primer(*args, **kwargs):
       gen = func()
       next(gen)
       return gen
   return primer

@coroutine
def sumer():
    total = 0
    term = 0
    while True :
        term = yield total
        print('term recieved')
        total += term

su = sumer()
print('EX2-1 -', su.send(0))
print(getgeneratorstate(su))
print('EX2-1 -', su.send(100))

让我们逐步检查您的代码。

coroutine 装饰器将 return 它的内部函数是 primer 就是这样......所以在你将 @coroutine 应用到 sumersumer 标签现在指向 primer 函数。

接下来,当您在 su = sumer() 行调用 primer 函数时,它将在 gen = func() 行创建一个协程,然后用 next(gen) 和 [=46= 初始化它] 是 primed 协程。

到目前为止 su 指向任何 primer 函数 returned,它是一个生成器而不是值 !

你的问题就在这里,如果 primer returns next(gen) 你会得到 0。但是 0 刚刚被跳过,您的协程现在已准备好接收值。

尝试改成:

from functools import wraps

def coroutine(func):
    @wraps(func)
    def primer(*args, **kwargs):
        gen = func()
        return next(gen)

    return primer


@coroutine
def sumer():
    total = 0
    while True:
        term = yield total
        print('term recieved')
        total += term


su = sumer()
print('EX2-1 -', su)

现在是 0,但不再有用了。 由于 su 不再是生成器,您不能将其传递给 getgeneratorstate 并向其发送值。现在是一个整数。