2016-04-06 18 views
5

私はC++のバックグラウンドを持ち、いくつかのPythonを学ぼうとしています。Late binding python closures

Whist私はC++の仮想関数を理解していますが、残念ながら、Pythonでクロージャの遅延バインディングが何を意味するのか分かりません。

リンク:https://gist.github.com/deemson/8efabf56d67623ead804

コピーパスタチュートリアルから:まさにここで何が起こっている

functions = [] 
for n in [1, 2, 3]: 
    def func(x): 
     return n*x 
    functions.append(func) 

# You would expect this to print [2, 4, 6] 
print(
    'calling a list of bad closures and output is: {}' 
    .format(str([function(2) for function in functions])) 
) 

?関数がリストに追加されると、その値はどのような値になりますか?私が理解できるように、このコードを簡略化してください。

答えて

1

これは、実行時に関数を作成することができます。多かれ少なかれ、lambdasのようにC++で作成することができます。だから、基本的にあなたがリストを反復処理しているので、1,2 and 3

for n in [1, 2, 3]: 
    def func(x): 
     return n*x 

nテイク値を作るには、あなたがして、FUNCという名前の関数を構築している各反復によって値をとり、n個のためにそれを掛けます。関数リストに追加することで、この関数が保存されるので、関数を呼び出すためにリストを反復処理することができます。これにより

[function(2) for function in functions] 

あなたが値2で保存された各機能を呼び出すには、出力[2, 4, 6]にこれを期待する([1 * 2、* 2 2、3 * 2])が、代わりにそれは[6, 6, 6]を返します。何故ならば、すべての関数は計算のためにnを使用しているからです。実際には1*x, 2*x and 3*xを実行していませんが、実際にはn*xになり、最後にxが3にバインドされているので3*2になると6になります。

pythonコンソールで適切に確認してください。

0

C++の言語では、関数へのポインタがリストに追加されています。 forループの後に、functionsは、3つの異なる機能(func(x) = n * x,func(x) = n * xおよびfunc(x) = n * x)へのポインタを含む。 nへの依存性に注意してください。 nが変化すると、これらの関数の動作も同様になり、それらはすべて同等です。

コードの2番目の部分では、ポインタがリストから抽出され、3つの関数のそれぞれが引数2で評価されます。

ここでは、明確にするための例を示します。

>>> functions 
[<function func at 0x0239AA70>, <function func at 0x0239AAB0>, <function func at 0x0239AB30>] 
>>> g = functions[2] 
>>> g 
<function func at 0x0239AB30> 
>>> g(10) 
20 
>>> g(100) 
200 

最初の行には、3つの異なる機能へのポインタが含まれていることがわかります。次の行は、リストから3番目のポインタ(func(x) = n * xを参照)を抽出し、それをgに割り当てます。効果的には、この呼び出しで関数g(x) = n * xを定義しました。我々は今引数でgを評価することができます。

すべての関数はnに依存するため、nを変更すると動作が変わることに注意してください。

>>> n = 100 
>>> g(10) 
1000 
+0

[6 6 6] – RickMota

+0

の代わりにyeild [2 4 6]ではないでしょうか?ダニエルの答えは正しい - 彼は私がしなかったものをキャッチしました。それらはすべてnを参照し、nは最後に2の値に収まるので、すべての関数はまったく同じように動作します。 – Christian

+0

私はnに依存することについて言及したが、C++のポインタへの接続を明確にするためにソリューションを投稿したままにしておきました。 – Christian