Python yield(从Ruby迁移):如何在没有参数的情况下编写函数,并且只能使用yield进行打印?

hel*_*sIT 7 ruby python yield generator proc

我一直在将Ruby代码转换为Python代码,现在我坚持使用包含以下内容的函数yield:

def three_print():
    yield
    yield
    yield
Run Code Online (Sandbox Code Playgroud)

我想调用该函数并告诉它打印"Hello"三次,因为这三个yield语句.由于函数不接受任何参数,我得到一个错误.你能告诉我最简单的方法吗?谢谢.

Dan*_*sky 12

yield在Ruby和yieldPython中有两个截然不同的东西.

在Ruby中yield运行一个作为参数传递给函数的块.

红宝石:

def three
  yield
  yield
  yield
end

three { puts 'hello '} # runs block (prints "hello") three times
Run Code Online (Sandbox Code Playgroud)

在Python中yield从生成器(它是一个使用的函数yield)抛出一个值并停止执行该函数.所以它是完全不同的东西,更有可能你希望将函数作为参数传递给Python中的函数.

蟒蛇:

def three(func):
  func()
  func()
  func()

three(lambda: print('hello')) # runs function (prints "hello") three times
Run Code Online (Sandbox Code Playgroud)

Python生成器

下面的代码(您提供的代码)是一个返回None三次的生成器:

def three():
   yield
   yield
   yield

g = three() #=> <generator object three at 0x7fa3e31cb0a0>
next(g) #=> None
next(g) #=> None
next(g) #=> None
next(g) #=> StopIteration
Run Code Online (Sandbox Code Playgroud)

我可以想象它是如何用于打印"Hello"三次的唯一方法 - 使用它作为迭代器:

for _ in three():
    print('Hello')
Run Code Online (Sandbox Code Playgroud)

Ruby类比

你可以在Ruby中做类似的事情Enumerator.new:

def three
  Enumerator.new do |e|
    e.yield # or e << nil
    e.yield # or e << nil
    e.yield # or e << nil
  end
end

g = three
g.next #=> nil
g.next #=> nil
g.next #=> nil
g.next #=> StopIteration

three.each do
  puts 'Hello'
end
Run Code Online (Sandbox Code Playgroud)

  • 您应该提到与 [Python `yield` **keyword**](https://docs.python.org/3.7/reference/expressions.html#yieldexpr) 等效的 Ruby 是 [Ruby `Enumerator::Yielder #yield` **method**](http://ruby-doc.org/core/Enumerator.html#method-c-new)(也别名为`Enumerator::Yielder#&lt;&lt;`,并且都没有正确记录, 很遗憾)。 (2认同)

use*_*ica 7

yield在Python中不像Ruby那样工作.特别是,它并不意味着"在这里执行块参数".此函数永远不会执行回调.

在Python中,yield用于创建迭代器(特别是生成器),并且您发布的函数将返回生成None3次的迭代器.你可以遍历迭代器并为每个值打印"Hello",忽略None:

for _ in three_print():
    print("Hello")
Run Code Online (Sandbox Code Playgroud)

这是你最接近Ruby行为的,但在底层机制方面仍然存在根本的不同.

另外,如果你这样做想,将执行一个回调3倍的功能,这将是

def f(callback):
    callback()
    callback()
    callback()
Run Code Online (Sandbox Code Playgroud)

你可以称之为

f(lambda: print("Hello"))
Run Code Online (Sandbox Code Playgroud)