简体   繁体   English

Python产量与Ruby产量

[英]Python yield vs Ruby yield

In Ruby, the yield keyword is used to yield to closures for blocks of execution. 在Ruby中,yield关键字用于产生执行块的闭包。

How does this keyword differ in the Python language? 这个关键字在Python语言中有何不同?

In ruby , yield is a shortcut that is used to call an anonymous function. 在ruby中 ,yield是用于调用匿名函数的快捷方式。 Ruby has a special syntax for passing an anonymous function to a method; Ruby有一个特殊的语法,用于将匿名函数传递给方法; the syntax is known as a block . 语法称为block Because the function has no name, you use the name yield to call the function: 因为函数没有名称,所以使用名称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

In python , when you see yield inside a function definition, that means that the function is a generator . 在python中 ,当你在函数定义中看到yield时,这意味着函数是一个generator A generator is a special type of function that can be stopped mid execution and restarted. 生成器是一种特殊类型的函数,可以在执行期间停止并重新启动。 Here's an example: 这是一个例子:

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))

output: 输出:

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

More code: 更多代码:

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

output: 输出:

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

From the output, you can see that yield causes a result to be returned; 从输出中,您可以看到yield会导致返回结果; then execution is immediately halted. 然后执行立即停止。 When you call next() again on the generator, execution continues until the next yield statement is encountered, which returns a value, then execution halts again. 当您在生成器上再次调用next()时,继续执行直到遇到下一个yield语句,该语句返回一个值,然后执行再次停止。

In Ruby, yield is used to bounce control to block( like anonymous function) to execute the block's statements and then bounce back to where the block's called. 在Ruby中, yield用于反弹控制以阻止(如匿名函数)执行块的语句,然后反弹回到块的调用位置。

With yield args you can pass arguments to the block, and also with lvar = yield you can get whatever returned and bind it to lvar after control exits the block. 使用yield args您可以将参数传递给块,并且使用lvar = yield您可以获得返回的任何内容,并在控制退出块后将其绑定到lvar It's a much general and consistent feature design in Ruby. 这是Ruby中一个通用且一致的特性设计。 And of course, you can apply this idea to iterating over collections. 当然,您可以将此想法应用于迭代集合。

Whereas in Python, mostly people use yield to facilitate effective access of items over somewhat collection, they focus on iterate once and generate on the fly once being called idea, which is the main use of yield in Python. 而在Python中,大多数人使用yield来促进项目的有效访问而不是某种集合,他们专注于迭代一次并且在被称为 idea时动态生成,这是Python中yield的主要用途。

FYI, It's not quite a distinguished feature between Python and Ruby on yield , at least on the way to use it. 仅供参考,至少在使用它的方式上,它在Python和Ruby之间的产量并不是很明显。 (Apparently they are implemented differently, as for python, yield creates a generator, which will not run any code unless the iteration starts). (显然它们的实现方式不同,对于python, yield会创建一个生成器,除非迭代开始,否则不会运行任何代码)。 For example, the way yield is used in python contextmanager is quite the same in Ruby. 例如,在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

here, yield pass file handle to with , and execute with-statements exactly once and then bounce back to file close statement 在这里, 产量文件句柄 ,并与语句执行一次 ,以及随后反弹至文件关闭声明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM