Python-3.2协程:AttributeError:'generator'对象没有属性'next'

25 python python-3.x

#!/usr/bin/python3.2
import sys

def match_text(pattern):
    line = (yield)
    if pattern in line:
        print(line)

x = match_text('apple')
x.next()

for line in input('>>>> '):
    if x.send(line):
        print(line)

x.close()
Run Code Online (Sandbox Code Playgroud)

这是一个协程,但Python3.2将其视为生成器 - 为什么?这里发生了什么?我指的是David Beazeley编写的Python Essential Reference:20.

引用相关部分:

Normally, functions operate on a single set of input arguments. However, a function can
also be written to operate as a task that processes a sequence of inputs sent to
it.This type of function is known as a coroutine and is created by using the yield 
statement as an expression (yield) as shown in this example:
 def print_matches(matchtext):
   print "Looking for", matchtext
   while True:
     line = (yield)       # Get a line of text
     if matchtext in line:
       print line

To use this function, you first call it, advance it to the first (yield), and then 
start sending data to it using send(). For example:
>>> matcher = print_matches("python")
>>> matcher.next() # Advance to the first (yield)
Looking for python
>>> matcher.send("Hello World")
>>> matcher.send("python is cool")
python is cool
>>> matcher.send("yow!")
>>> matcher.close() # Done with the matcher function call
Run Code Online (Sandbox Code Playgroud)

为什么我的代码不起作用 - 而不是DB的工作..

deathstar> python3.2 xxx   
Traceback (most recent call last):
  File "xxx", line 9, in <module>
    matcher.next() # Advance to the first (yield)
AttributeError: 'generator' object has no attribute 'next'
Run Code Online (Sandbox Code Playgroud)

Kar*_*tel 45

您将被错误消息抛弃; 类型方面,Python没有区别 - 你可以.send使用任何东西yield,即使它没有对内部发送的值做任何事情.

在3.x中,不再有.next这些方法; 相反,使用内置的免费功能next.

  • 具体来说,协议进行了更改,以便 Python 需要“.__next__”方法,而不是“.next”来实现逻辑。(迭代也可以通过使 `.__iter__` 方法成为生成器函数来实现。)无论如何,都应该使用自由函数 `next`:按照惯例,每个以 `__` 开头和结尾的方法名称都用于特殊的、幕后目的,不应直接从类外部调用。如果由于某种原因您被迫分别使用 Windows XP 或 7 的 Python 等效项,那么这也适用于 2.6 和 2.7。 (2认同)

小智 7

对于python 3.2版next(),内置函数的语法应为matcher.__next__()next(matcher)


sag*_*age 5

如果您发现自己正在修补某人的代码,那么似乎内置的 python3 next() 函数调用了迭代器的next () 函数,因此您可以像我刚才那样.next(使用 python3-tolerable查找/替换某人的 python2.__next__(使 primefac 模块的一部分在 python3 中工作(以及其他微不足道的更改)。

这是参考

下一个(迭代器[,默认])

通过调用其next () 方法从迭代器中检索下一项。如果给出默认值,则在迭代器耗尽时返回,否则引发 StopIteration。