2009-03-12 14 views
4

スタックレスが現在実行されていないので、自分で試すことはできません。スタックレスPythonでは、チャネル経由でチャネルを送信できますか?

import stackless 
ch1 = stackless.channel() 
ch2 = stackless.channel() 

ch1.send(ch2) 
ch3 = ch1.receive() 

は、同じチャネルCH2CH3ていますか?セイ:

text = "Hallo" 
ch2.send(text) 
assert text == ch3.receive() 

この機能は、(Plan9名声の)ロバート・パイクをGoogleで与えたtalk about Newsqueakを思い出しました。 Newsqueakではチャンネルを介してチャンネルを送ることができます。

+0

これは面白いですが、私はStacklessについて正確なことを考えていましたが、Go/Newsqueakのようなチャンネルがあるのが大好きです。 – Jyaan

答えて

4

はい。ただテストされた。

>>> import stackless 
>>> ch1 = stackless.channel() 
>>> def a(): 
... ch2 = stackless.channel() 
... ch1.send(ch2) 
... ch2.send("Hello") 
... 
>>> def b(): 
... ch3 = ch1.receive() 
... print ch3.receive() 
... 
>>> stackless.tasklet(a)() 
<stackless.tasklet object at 0x01C6FCB0> 
>>> stackless.tasklet(b)() 
<stackless.tasklet object at 0x01C6FAB0> 
>>> stackless.run() 
Hello 
3

チャネルは通常のPythonリファレンスを送信するので、送信するデータ(チャンネル、文字列など)は正確に受信されるものです。

チャネルを介してチャネルを送信する例は、タスクレットをサービスとして使用する場合です。つまり、タスクレットは要求をチャネルでリッスンし、動作し、結果を返します。要求には作業のデータと結果の戻りチャネルが含まれている必要があり、その結果が要求者に送られます。

ここ数年前に私がStackless talk at PyConのために開発した極端な例です。これは関数呼び出しごとに新しいタスクレットを作成するので、Pythonのスタック制限を気にする必要がない階乗の再帰的実装を使用できます。各コールにタスクレットを割り当て、結果の戻りチャネルを取得します。

import stackless 

def call_wrapper(f, args, kwargs, result_ch): 
    result_ch.send(f(*args, **kwargs)) 
    # ... should also catch and forward exceptions ... 

def call(f, *args, **kwargs): 
    result_ch = stackless.channel() 
    stackless.tasklet(call_wrapper)(f, args, kwargs, result_ch) 
    return result_ch.receive() 

def factorial(n): 
    if n <= 1: 
     return 1 
    return n * call(factorial, n-1) 

print "5! =", factorial(5) 
print "1000!/998! =", factorial(1000)/factorial(998) 

出力は次のようになります。

5! = 120 
1000!/998! = 999000 

は、私は私のプレゼンテーションのチャネル上のチャネルを送信するいくつかの他の例を持っています。 Stacklessではよくあることです。

関連する問題