简体   繁体   English

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

[英]Python yield (migrating from Ruby): How can I write a function without arguments and only with yield to do prints?

I've been converting Ruby code to Python code and now I'm stuck with this function that contains yield : 我一直在将Ruby代码转换为Python代码,现在我坚持使用包含yield函数:

def three_print():
    yield
    yield
    yield

I would like to call the function and tell it to print "Hello" three times because of the three yield statements. 由于三个yield语句,我想调用该函数并告诉它打印“Hello”三次。 As the function does not take any arguments I get an error. 由于函数不接受任何参数,我得到一个错误。 Can you tell me the easiest way to get it working? 你能告诉我最简单的方法吗? Thank you. 谢谢。

yield in Ruby and yield in Python are two very different things. yield在Ruby和yield在Python是两个完全不同的事情。

In Ruby yield runs a block passed as a parameter to the function. 在Ruby中, yield运行一个块作为参数传递给函数。

Ruby: 红宝石:

def three
  yield
  yield
  yield
end

three { puts 'hello '} # runs block (prints "hello") three times

In Python yield throws a value from a generator (which is a function that uses yield ) and stops execution of the function. 在Python中, yield从生成器抛出一个值(这是一个使用yield的函数)并停止执行该函数。 So it's something completely different, more likely you want to pass a function as a parameter to the function in Python. 所以它是完全不同的东西,更有可能你希望将函数作为参数传递给Python中的函数。

Python: 蟒蛇:

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

three(lambda: print('hello')) # runs function (prints "hello") three times

Python Generators Python生成器

The code below (code you've provided) is a generator which returns None three times: 下面的代码(您提供的代码)是一个返回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

The only way that I can imagine how it could be used for printing "Hello" three times -- using it as an iterator: 我可以想象它是如何用于打印“Hello”三次的唯一方法 - 使用它作为迭代器:

for _ in three():
    print('Hello')

Ruby Analogy Ruby类比

You can do a similar thing in Ruby using Enumerator.new : 你可以使用Enumerator.new在Ruby中做类似的事情:

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

yield in Python doesn't work like in Ruby. Python中的yield不像Ruby那样有效。 In particular, it doesn't mean "execute the block argument here". 特别是,它并不意味着“在这里执行块参数”。 This function will never execute callbacks. 此函数永远不会执行回调。

In Python, yield is for creating iterators (specifically generators), and the function you've posted will return an iterator that produces None 3 times. 在Python中, yield用于创建迭代器(特别是生成器),并且您发布的函数将返回一个生成None 3次的迭代器。 You can loop over the iterator and print "Hello" for each value, ignoring the None : 您可以遍历迭代器并为每个值打印“Hello”,忽略None

for _ in three_print():
    print("Hello")

which is the closest you'd get to the Ruby behavior, but still fundamentally different in terms of underlying mechanics. 这是你最接近Ruby行为的,但在底层机制方面仍然存在根本的不同。

Alternatively, if you do want a function that will execute a callback 3 times, that would be 另外,如果想将执行的回调3倍的功能,这将是

def f(callback):
    callback()
    callback()
    callback()

and you could call it as 你可以称之为

f(lambda: print("Hello"))

You can use : 您可以使用 :

def three_print():
  yield"Hello\n"*3
print(''.join(list(three_print())))

# Hello
# Hello
# Hello

You can yield in a loop: 你可以循环屈服:

def hello():
   for i in range(3):
      yield "hello"

print(list(hello()))

Output: 输出:

['hello', 'hello', 'hello']

In Python3.3 and greater, you can use the yield from statement: 在Python3.3及更高版本中,您可以使用yield from语句:

def hello():
   yield from ["hello" for i in range(3)]

print(list(hello()))

Output: 输出:

['hello', 'hello', 'hello']
def three_print():
  yield("Hello")
  yield("Hello")
  yield("Hello")

since there are three yields , you need to call three_print().next() three times to get the "Hello" string to output 因为有三个yields ,你需要调用three_print().next()三次以获得"Hello"字符串输出

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

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