2013-07-24 57 views
2
#def func(param): 
# if param < 0: 
#  return "test" 
# i = 0 
# while i < param: 
#  yield i 
#  i += 1 
def func(param): 
    if param < 0: 
     return "test" 
    def gen(n): 
     i = 0 
     while i < param: 
      yield i 
      i += 1 
    return gen(param) 

print(func(-1)) 
print(func(3)) 
g = func(3) 
for i in range(0, 3): 
    print(next(g)) 

是否有一个Python解释器无法隐式地将注释代码转换为实际代码的原因?这似乎应该是允许的,但我想知道是什么影响,使他们选择不接受这一点。为什么Python解释器不隐式创建生成器?

回答

0

原因很简单,如果def包含yield声明,它创建了一个发电机:

http://www.python.org/dev/peps/pep-0255/

yield语句只能在函数内部使用。一个函数 包含一个yield语句被称为生成器函数。发电机 功能是在各方面的普通函数对象,但代码中的对象的co_flags成员设置 新CO_GENERATOR标志。

这就是解释器如何区分正则函数和生成器函数。这很容易推理(“如果它包含yield,它是一个生成器”)

您描述的“条件生成器”行为将会实现起来要复杂得多,并且在某些情况下不可取(可能条件应该在发生器的第一次迭代中发生,或者它应该在您呼叫时立即运行func(...)

您的其他代码要么返回一个生成器,要么返回一个字符串。如果这是你想要的界面,这似乎是一个完美的解决方案(但很难使实际的建议没有一个真实的例子)

1

当你调用一个生成器函数时,你知道它将返回什么类型的对象 - 一个生成器。如果我们允许生成器函数为return,那么在开始迭代生成器之前,您必须检查返回值的类型,以便不再有生成器函数 - 只是一个可能返回生成器的函数。

0

发电机声明如下功能,但不同的, 你不能在发电机 使用return语句是你应该做的是:

def func(param): 
    if param < 0: 
     yield "test" 
     raise StopIteration() 
    i = 0 
    while i < param: 
     yield i 
     i += 1 

一个更好的implmention是:

def func(param): 
    if param < 0: 
     raise ValueError("param must be a positive number") 
    i = 0 
    while i < param: 
     yield i 
     i += 1 
2

在python2.x中,你不能在生成器中返回一些东西:

>>> def func(): 
...  return 3 
...  yield 3 
... 
    File "<stdin>", line 3 
SyntaxError: 'return' with argument inside generator 
>>> 

在python3.x,使用return在发电机意味着养StopIteration(<something>)

>>> def func(): 
...  return 3 
...  yield 3 
... 
>>> func().__next__() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration: 3 
>>> 

我想不出任何理由解释来决定哪个部分是一台发电机。这很难,我认为这是程序员的责任。我甚至怀疑在生成器中返回值是否是一个很好的实现。

+0

我认为功能已经走了,但是我永远无法在第一时间之后再次找到源我读过它,我没有安装Python 3进行测试。你有一个PEP链接或记录变化的东西吗? – user2357112

+1

[PEP380](http://www.python。组织/开发/ PEPS/PEP-0380 /)。你可以看到这个规则:@ user2357112 – zhangyangyu

+3

从技术上讲,你可以在Python 2.x的生成器中使用'return' - 你不能返回一个值。这相当于提高'StopIteration'。 – Amber

相关问题