我一直在寻找代码来在终端中旋转光标并找到它。我想知道代码中发生了什么。特别是for c in spinning_cursor():
我从未见过这种语法。是因为我一次使用yield
从生成器返回一个元素,并将其分配给c?在y()中使用x的任何其他例子?
import sys
import time
def spinning_cursor():
cursor='/-\|'
i = 0
while 1:
yield cursor[i]
i = (i + 1) % len(cursor)
for c in spinning_cursor():
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
答案 0 :(得分:46)
使用yield
将函数转换为generator。生成器是iterator的特殊类型。 for
总是循环遍历iterables,依次获取每个元素并将其分配给您列出的名称。
spinning_cursor()
返回一个生成器,spinning_cursor()
内的代码实际上不会运行,直到你开始迭代生成器。迭代生成器意味着函数中的代码被执行,直到它遇到yield
语句,此时表达式的结果将作为下一个值返回并再次暂停执行。
for
循环就是这样,它会在生成器上调用等效的next()
,直到生成器发出信号通过引发StopIteration
来完成(当函数发生时)回报)。每个返回值next()
依次分配给c
。
您可以通过在Python提示符中创建生成器来查看:
>>> def spinning_cursor():
... cursor='/-\|'
... i = 0
... while 1:
... yield cursor[i]
... i = (i + 1) % len(cursor)
...
>>> sc = spinning_cursor()
>>> sc
<generator object spinning_cursor at 0x107a55eb0>
>>> next(sc)
'/'
>>> next(sc)
'-'
>>> next(sc)
'\\'
>>> next(sc)
'|'
这个特定的生成器永远不会返回,所以StopIteration
永远不会被引发,for
循环将永远继续,除非你杀死脚本。
答案 1 :(得分:5)
在Python中,for语句允许您迭代元素。
Python的for语句按照它们在序列中出现的顺序迭代任何序列(列表或字符串)的项目
此处,元素将是spinning_cursor()
的返回值。
答案 2 :(得分:3)
for c in spinning_cursor()
语法是for-each
循环。它将迭代spinning_cursor()
返回的迭代器中的每个项目。
循环内部将:
\b
,它被解释为退格(删除最后一个字符)。请注意,这发生在循环结束时,因此在第一次迭代期间不会写入,并且它在步骤1中共享刷新调用。 spinning_cursor()
将返回generator,在您开始迭代之前,它实际上不会运行。看起来它将永远循环遍历'/-\|'
。这有点像有一个无限的列表来迭代。
因此,最终输出将是ASCII微调器。在你杀死剧本之前,你会看到这些角色(在同一个地方)重复。
/
-
\
|
答案 3 :(得分:2)
spinning_cursor函数返回一个iterable(来自yield的生成器)。
for c in spinning_cursor():
与
相同 for i in [1, 2, 3, 4]:
答案 4 :(得分:2)
spinning_cursor
相同的结果。 itertools充满了迭代器和函数的优秀示例,以帮助创建自己的迭代器。它可能会帮助您更好地理解迭代器。
import sys, time, itertools
for c in itertools.cycle('/-\|'):
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')