2017-08-26 55 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 
相關問題