【发布时间】:2010-12-14 20:18:24
【问题描述】:
Python中的yield关键字和C#中的yield关键字有什么区别?
【问题讨论】:
Python中的yield关键字和C#中的yield关键字有什么区别?
【问题讨论】:
C# 的 yield return 相当于 Python 的 yield ,而 yield break 在 Python 中只是 return。
除了那些细微的差别之外,它们的用途基本相同。
【讨论】:
return; yield 来获取一个空的生成器。
yield 是一个可以从迭代站点接收值的表达式。 yield return 是一个声明。
最重要的区别是python yield 给你一个迭代器,一旦它完全迭代就结束了。
但是 C# yield return 为您提供了一个迭代器“factory”,您可以将它传递并在代码的多个位置使用它,而无需考虑它之前是否已“循环”过一次。
以python为例:
In [235]: def func1():
.....: for i in xrange(3):
.....: yield i
.....:
In [236]: x1 = func1()
In [237]: for k in x1:
.....: print k
.....:
0
1
2
In [238]: for k in x1:
.....: print k
.....:
In [239]:
在 C# 中:
class Program
{
static IEnumerable<int> Func1()
{
for (int i = 0; i < 3; i++)
yield return i;
}
static void Main(string[] args)
{
var x1 = Func1();
foreach (int k in x1)
Console.WriteLine(k);
foreach (int k in x1)
Console.WriteLine(k);
}
}
这给了你:
0
1
2
0
1
2
【讨论】:
除了其他答案之外,需要注意的一个重要区别是 C# 中的 yield 不能用作表达式,只能用作语句。
yield 表达式在 Python 中的用法示例(示例粘贴自 here):
def echo(value=None):
print "Execution starts when 'next()' is called for the first time."
try:
while True:
try:
value = (yield value)
except GeneratorExit:
# never catch GeneratorExit
raise
except Exception, e:
value = e
finally:
print "Don't forget to clean up when 'close()' is called."
generator = echo(1)
print generator.next()
# Execution starts when 'next()' is called for the first time.
# prints 1
print generator.next()
# prints None
print generator.send(2)
# prints 2
generator.throw(TypeError, "spam")
# throws TypeError('spam',)
generator.close()
# prints "Don't forget to clean up when 'close()' is called."
【讨论】:
IEnumerable<T> 上调用 GetEnumerator 来实现,您将从 yielding 方法返回。跨度>
yield 关键字的差异,而不是返回的生成器/迭代器对象的处理方式的差异
GetEnumerator,您也无法将值传递给生成器函数,这就是yield 表达式在 Python 版本中计算。 IEnumerator 接口上没有与 Python 的 send() 生成器方法的语义相匹配的方法。