[英]Understanding generator functions in Python
Why it outputs None
? 为什么输出None
?
def hello():
print("hello")
def gen():
yield hello();
yield hello();
yield hello();
for x in gen():
print(x)
result is: 结果是:
hello
None
hello
None
hello
None
why None is printed?? 为什么不打印? not hello * 3 ? 不是* 3吗?
Why it prints None : 为什么打印无 :
Here when you print()
but doesnt return
anything, python will add a return
automatically at the end. 在这里,当您print()
但不return
任何内容时,python会在末尾自动添加一个return
。
Let's see an example using dis
我们来看一个使用dis
的例子
import dis
def hello():
print('hello')
dis.dis(hello)
output: 输出:
0 LOAD_CONST 1 ('hello')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Let's see now when you return an explicit values: 现在让我们看一下您返回的显式值:
import dis
def hello():
return 'hello'
dis.dis(hello)
output: 输出:
0 LOAD_CONST 1 ('hello')
3 RETURN_VALUE
See, the LOAD_CONST 0 (None)
was not called the second times. 请参见,第二次未调用LOAD_CONST 0 (None)
。 Therefore, the first value being loaded was return. 因此,要加载的第一个值是return。
What you should do to improve your code : 您应该做什么来改善您的代码 :
Do this, if you just need to print "hello" inside the hello
function. 如果只需要在hello
函数中打印“ hello”,请执行此操作。
def hello():
print("hello")
def gen():
yield hello()
yield hello()
yield hello()
for x in gen():
x
OR, use return value, in that case you need to return instead of printing. 或者,使用返回值,在这种情况下,您需要返回而不是打印。
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)
But it is weird to call several yield
, better do a loop to avoid a StopIteration
但是调用多个yield
很奇怪,最好做一个循环以避免StopIteration
eg 例如
def hello():
return "hello"
def gen():
while True:
yield hello()
x = gen()
for i in range(3):
print(x.next())
By default functions return None
type. 默认情况下,函数返回None
类型。
def hello():
pass
def gen():
yield hello();
yield hello();
yield hello();
for x in gen():
print(x)
Output: 输出:
None
None
None
The main difference between generators and functions is that you can obtain values on the fly. 生成器和函数之间的主要区别在于,您可以即时获取值。 And after one value is yield
'ed by the generator. 和一个值后yield
由发电机“编 and next value is returned the old one is not stored in the memory . 返回下一个值,旧值不存储在内存中 。
def hello():
for x in range(3):
yield x*x
for i in hello():
print(i)
Output: 输出:
0
1
4
Now using next()
现在使用next()
def hello():
for x in range(3):
yield x*x
gen = hello()
for i in range(3):
print(next(gen))
Output: 输出:
0
1
4
So far so good. 到现在为止还挺好。 Right? 对? gen = hello()
here gen
becomes a generator object. gen = hello()
在这里, gen
成为生成器对象。
my_list = [x*x for x in range(3)]
for i in my_list:
print(i)
Output: 输出:
0
1
4
Same output? 输出相同吗? Yes same output. 是相同的输出。 But only difference here is that I can use the my_list
iterable any number of times I want, 但唯一的区别是我可以任意多次使用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)
Output: 输出:
0
1
4
0
1
4
However if I try to use the Generator when it is exhausted. 但是,如果在电量耗尽时尝试使用发电机 。
def hello():
for x in range(3):
yield x*x
gen = hello()
for i in range(3):
print(next(gen))
next(gen)
Output 输出量
0
1
4
Traceback (most recent call last):
File "/home/mr/sadas.py", line 12, in <module>
print(next(gen))
StopIteration
How to overcome this? 如何克服呢? Create a new generator object again and use. 再次创建一个新的生成器对象并使用。
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))
Output: 输出:
0
1
4
0
1
4
You see the difference? 你看到区别了吗? Hope I was clear. 希望我很清楚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.