2017-08-26 68 views
2

我一直在Ruby代码转换为Python代码,现在我坚持了这个功能,它包含yieldPython收益率(从Ruby迁移):如何在不带参数的情况下编写函数,并仅使用yield来进行打印?

def three_print(): 
    yield 
    yield 
    yield 

我想调用该函数并告诉它打印出“你好”三次,因为三个yield报表。由于该函数没有任何参数,我得到一个错误。你能告诉我让它工作的最简单方法吗?谢谢。

+0

比增加了一个参数其他? –

+4

请注意,Ruby中的yield关键字与Python中的yield关键字具有非常不同的行为。 –

+1

**注意潜在答案:**请仔细阅读问题。 OP正在寻找将_specific semantics_从ruby转换为Python的代码。像print('Hello \ n'* 3)'这样的答案在技术上是正确的,但他们却忽略了最重要的一点:Ruby vs Python中yield关键字的行为。 –

回答

7

在Ruby中yieldyield在Python中是两个完全不同的东西。

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

红宝石:

def three 
    yield 
    yield 
    yield 
end 

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

在Python yield从发电机抛出一个值(这是一个使用yield的函数),并停止该功能的执行。所以它是完全不同的,更有可能你想把一个函数作为参数传递给Python中的函数。

的Python:

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

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

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 

的唯一途径我可以想象如何将它用于三次打印“Hello” - 将其用作迭代器:

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

红宝石比喻

你可以使用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 
+0

你应该提到,Ruby的等价物[Python'yield' ** keyword **](https://docs.python.org/3.7/reference/expressions.html#yieldexpr)是[Ruby'Enumerator :: Yielder#yield **方法**](http://ruby-doc.org/core/Enumerator.html#method-c-new)(也可以是'Enumerator :: Yielder#<<'的别名,记录在案,不幸)。 –

+0

@JörgWMittag感谢您的通知,我已将它添加到答案中 –

0

您可以在一个循环中产生:

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

print(list(hello())) 

输出:

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

在Python3.3和更大的,你可以使用yield from声明:

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

print(list(hello())) 

输出:

['hello', 'hello', 'hello'] 
+0

Minor nitpick:''yield''语法仅在Python _3.3_及更高版本中可用。请参阅[这里](https://www.python.org/dev/peps/pep-0380/)。 –

+0

@ChristianDean谢谢!我不知道。现在修复。 – Ajax1234

+0

_Eh_,仍然不完全正确。它只能在Python 3.3或更高版本中使用。任何Python 3.x版本都不行。它需要特别是Python 3.3+。 –

0
def three_print(): 
    yield("Hello") 
    yield("Hello") 
    yield("Hello") 

,因为有三个yields,你需要调用three_print().next()三次获得"Hello"字符串输出

7

yield在Python并不像Ruby的工作。特别是,它并不意味着“在这里执行块参数”。这个函数永远不会执行回调。

在Python中,yield用于创建迭代器(特别是生成器),并且您发布的函数将返回一个迭代器,该迭代器将产生3次None。你也可以遍历迭代器和打印“你好”每个值,忽略None

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

这是你得到了Ruby行为最接近的,但仍处于底层机制方面有着根本的不同。

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

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

,你可以把它作为

f(lambda: print("Hello")) 
1

您可以使用:

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

# Hello 
# Hello 
# Hello 
相关问题