2016-02-25 122 views
5

在Ruby中,yield关键字用于产生执行块的闭包。Python收益率与Ruby收益率

此关键字在Python语言中有何不同?

+3

我会回答,但我想想[这](http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python)涵盖了它 – Alex

回答

8

在ruby中,yield是一个用于调用匿名函数的快捷方式。 Ruby具有将匿名函数传递给方法的特殊语法;该语法被称为block。由于该功能还没有名字,您使用的名称产生调用的函数:

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 

在蟒蛇,当你看到一个函数的定义,这意味着该函数是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)) 

输出:

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

+3

基本上,Python的'yield'关键字等同于Ruby的'Enumerator: :Yielder#yield'。 –

+0

谢谢!我不知道Enumerator :: Yielder类! – noname

+0

关于'Enumerator :: Yielder'和'Enumerator :: Generator'的更多细节我推荐:http://patshaughnessy.net/2013/4/3/ruby-2-0-works-hard-so-you-可待懒 –

1

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

随着yield args你可以传递参数来将挡,并与lvar = yield 你可以得到什么回来了,它控制退出块之后绑定到LVAR。这是Ruby中一个非常普遍且一致的功能设计。当然, 你可以应用这个想法迭代集合。

而在Python中,大部分人使用产量,以方便项目在一定程度上收集有效访问,他们专注于迭代一次,并实时生成,一旦被称为的想法,这是主要的使用产量的在Python中。

仅供参考,至少在使用它的方式上,Python和Ruby之间的差异性不大,收益率为。 (显然它们的实现方式不同,至于python,yield创建了一个生成器,除非迭代开始,否则它将不会运行任何代码)。例如,在Python中使用产生的方式在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 

这里,产量文件句柄,并执行与语句恰好一次,然后反弹至文件关闭声明