Python中的yield break

Son*_*Lee 50 python yield generator

根据这个问题的答案,C#中的yield break相当于python中的return.在正常情况下,'return'确实会停止发电机.但是如果你的函数除了返回之外什么都不做,你将获得一个None而不是一个空的迭代器,它在C#中由yield break返回

def generate_nothing():
    return

for i in generate_nothing():
    print i
Run Code Online (Sandbox Code Playgroud)

你会得到一个TypeError:'NoneType'对象是不可迭代的.但是如果我在返回之前添加一个从不运行的yield,这个函数会返回我期望的结果.

def generate_nothing():
    if False: yield None
    return
Run Code Online (Sandbox Code Playgroud)

如果有效,但似乎有线.谁有更好的主意?

谢谢,

Sam*_*ons 48

处理这个的一个好方法是提高StopIteration,这是当迭代器没有任何东西可以产生并被next()调用时引发的.这也将优雅地打破for循环,在循环中没有任何内容执行.

例如,给定一个元组(0, 1, 2, 3)我想要重叠对((0, 1), (1, 2), (2, 3)).我可以这样做:

def pairs(numbers):
    if len(numbers) < 2:
        raise StopIteration

    for i, number in enumerate(numbers[1:]):
        yield numbers[i], number
Run Code Online (Sandbox Code Playgroud)

现在可以pairs安全地处理1个或更少的列表.

  • 请注意,从vs 3.6开始这是一个坏主意,因为随着[PEP 479](https://www.python.org/dev/peps/pep-0479/)的实施,`StopIteration`将被转换为`RuntimeError`以防止使用子生成器时出现问题. (15认同)
  • 任何版本都是个坏主意; 只是'返回'. (13认同)
  • 虽然这是有用的(现在),`return`更好; 所描述的功能甚至包含在[返回文档]中(https://docs.python.org/3/reference/simple_stmts.html#the-return-statement). (10认同)

nin*_*cko 45

def generate_nothing():
    return
    yield
Run Code Online (Sandbox Code Playgroud)

  • 这将创建代码,但在linters中无法访问警告。 (2认同)

phi*_*hag 6

def generate_nothing():
    return iter([])
Run Code Online (Sandbox Code Playgroud)

  • 或者`xrange(0)`(3.x中的`range(0)`. (2认同)
  • 这两者的速度大约是 return 的两倍;产量`。但请注意,这些将返回 `&lt;type 'listiterator'&gt;` 和 `&lt;type 'xrange'&gt;` 类型的对象,它们都是 `object` 的直接子类型 - 所以它们不是生成器。并不是说这很重要。仅仅是学术兴趣:-) (2认同)