繁体   English   中英

了解Python中的生成器函数

[英]Understanding generator functions in Python

为什么输出None

def hello():
    print("hello")

def gen():
    yield hello();
    yield hello();
    yield hello();

for x in gen():
    print(x)

结果是:

hello 
None 
hello 
None 
hello 
None

为什么不打印? 不是* 3吗?

为什么打印无

在这里,当您print()但不return任何内容时,python会在末尾自动添加一个return

我们来看一个使用dis的例子

import dis

def hello():
  print('hello')

dis.dis(hello)

输出:

      0 LOAD_CONST               1 ('hello')
      3 PRINT_ITEM          
      4 PRINT_NEWLINE       
      5 LOAD_CONST               0 (None)
      8 RETURN_VALUE    

现在让我们看一下您返回的显式值:

import dis

def hello():
  return 'hello'

dis.dis(hello)

输出:

    0 LOAD_CONST               1 ('hello')
    3 RETURN_VALUE  

请参见,第二次未调用LOAD_CONST 0 (None) 因此,要加载的第一个值是return。

您应该做什么来改善您的代码

如果只需要在hello函数中打印“ hello”,请执行此操作。

def hello():
    print("hello")

def gen():
    yield hello()
    yield hello()
    yield hello()

for x in gen():
    x

或者,使用返回值,在这种情况下,您需要返回而不是打印。

def hello():
    return "hello"
    ^ Here I return rather than print hello

def gen():
    yield hello()
    yield hello()
    yield hello()

for x in gen():
    print(x)

但是调用多个yield很奇怪,最好做一个循环以避免StopIteration

例如

def hello():
    return "hello"

def gen():
    while True:
        yield hello()

x = gen()

for i in range(3):
  print(x.next())

默认情况下,函数返回None类型。

def hello():
    pass

def gen():
    yield hello();
    yield hello();
    yield hello();

for x in gen():
    print(x)

输出:

None
None
None

什么是发电机?

生成器和函数之间的主要区别在于,您可以即时获取值。 和一个值后yield由发电机“编 返回下一个值,旧值不存储在内存中

在生成器上迭代

def hello():
    for x in range(3):
        yield x*x


for i in hello():
    print(i)

输出:

0
1
4

现在使用next()

def hello():
    for x in range(3):
        yield x*x

gen = hello()

for i in range(3):
    print(next(gen))

输出:

0
1
4

到现在为止还挺好。 对? gen = hello()在这里, gen成为生成器对象。

遍历列表

my_list = [x*x for x in range(3)]
for i in my_list:
    print(i)

输出:

0
1
4

输出相同吗? 是相同的输出。 但唯一的区别是我可以任意多次使用my_list迭代,

my_list = [x*x for x in range(3)]
for i in my_list:
    print(i)
print("\n")
for i in my_list:
    print(i)

输出:

0
1
4

0
1
4

但是,如果在电量耗尽时尝试使用发电机

def hello():
    for x in range(3):
        yield x*x

gen = hello()

for i in range(3):
    print(next(gen))
next(gen)

输出量

0
1
4
Traceback (most recent call last):
  File "/home/mr/sadas.py", line 12, in <module>
    print(next(gen))
StopIteration

如何克服呢? 再次创建一个新的生成器对象并使用。

def hello():
    for x in range(3):
        yield x*x

gen = hello()

for i in range(3):
    print(next(gen))

gen = hello()

for i in range(3):
    print(next(gen))

输出:

0
1
4
0
1
4

你看到区别了吗? 希望我很清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM