Python产量与Ruby产量

时间:2016-02-25 22:10:54

标签: python ruby yield

在Ruby中,yield关键字用于产生执行块的闭包。

这个关键字在Python语言方面有何不同?

2 个答案:

答案 0 :(得分:13)

在ruby 中,yield是一个用于调用匿名函数的快捷方式。 Ruby有一个特殊的语法,用于将匿名函数传递给方法;语法称为block。由于该函数没有名称,因此使用名称​​ yield 来调用函数:

def do_stuff(val)
  puts "Started executing do_stuff"
  yield(val+3)
  yield(val+4) 
  puts "Finshed executing do_stuff" 
end

do_stuff(10) {|x| puts x+3} #<= This is a block, which is an anonymous function
                            #that is passed as an additional argument to the 
                            #method do_stuff

--output:--
Started executing do_stuff
16
17
Finshed executing do_stuff

在python中,当你在函数定义中看到yield时,这意味着该函数是generator。生成器是一种特殊类型的函数,可以在执行期间停止并重新启动。这是一个例子:

def do_stuff(val):
    print("Started execution of do_stuff()")

    yield val + 3
    print("Line after 'yield val + 3'")
    yield val + 4
    print("Line after 'yield val + 4'")

    print("Finished executing do_stuff()")


my_gen = do_stuff(10)

val = next(my_gen)    
print("--received {} from generator".format(val))

输出:

Started execution of do_stuff()
--received 13 from generator

更多代码:

val = next(my_gen)    
print("--received {} from generator".format(val))

输出:

Line after 'yield val + 3'
--received 14 from generator

从输出中,您可以看到yield导致返回结果;然后执行立即停止。当你在生成器上再次调用next()时,继续执行直到遇到下一个yield语句,返回一个值,然后执行再次停止。

答案 1 :(得分:1)

在Ruby中, yield 用于弹出控制以阻止(如匿名函数)执行块的语句,然后弹回到块调用的位置。

使用yield args,您可以将参数传递给块,也可以传递lvar = yield 你可以得到任何返回的东西,并在控制退出块之后将其绑定到 lvar 。它是Ruby中一个通用且一致的功能设计。而且当然, 你可以将这个想法应用于迭代集合。

在Python中,大多数人使用 yield 来促进项目的有效访问,而不是集中收集,他们专注于迭代一次,并在被称为想法时即时生成,这是Python中 yield 的主要用途。

仅供参考,在 yield 上,Python和Ruby之间的区别并不是很明显,至少在使用它的方式上如此。 (显然它们的实现方式不同,对于python, yield 会创建一个生成器,除非迭代开始,否则不会运行任何代码)。例如,在python contextmanager中使用 yield 的方式在Ruby中是完全相同的。

from contextlib import contextmanager
@contextmanager
def openfile(name, mode):
    f= open(name, mode)
    yield f
    f.close()

with openfile('log.txt', 'r') as handle:
    for line in handle:
        print line

此处,产量文件句柄传递给 ,然后执行 with-statements 完全一次,然后退回到文件关闭声明