[解決済み] レキシカルクロージャーの仕組みを教えてください。
2022-04-27 06:01:32
質問
Javascriptのコードでレキシカルクロージャの問題を調査していたところ、Pythonでこの問題に行き当たりました。
flist = []
for i in xrange(3):
def func(x): return x * i
flist.append(func)
for f in flist:
print f(2)
この例では
lambda
. 4 4 4"と表示されるのは驚きです。私は"0 2 4"を期待します。
この同等のPerlのコードでは、正しく動作します。
my @flist = ();
foreach my $i (0 .. 2)
{
push(@flist, sub {$i * $_[0]});
}
foreach my $f (@flist)
{
print $f->(2), "\n";
}
"0 2 4"が印刷されます。
この違いを教えてください。
更新しました。
問題点
ではありません。
と
i
はグローバルである。これは、同じ動作を表示します。
flist = []
def outer():
for i in xrange(3):
def inner(x): return x * i
flist.append(inner)
outer()
#~ print i # commented because it causes an error
for f in flist:
print f(2)
コメント行にあるように
i
はその時点では不明です。それでも "4 4 4" と表示されます。
どのように解決するのですか?
Pythonは実際に定義通りの動作をしています。 3つの独立した関数 が作成されますが、それぞれ で定義された環境のクロージャになります。 - この場合、グローバル環境(ループが他の関数内に配置されている場合は、外側の関数の環境)です。これがまさに問題なのですが、この環境では iはミュータント であり、クロージャはすべて は同じ i を参照しています。 .
私が思いつく最善の解決策は、関数クリータを作成して、その関数クリータから あれ 代わりに これによって 異なる環境 は、作成された各関数に対して 異なるi をそれぞれ作成します。
flist = []
for i in xrange(3):
def funcC(j):
def func(x): return x * j
return func
flist.append(funcC(i))
for f in flist:
print f(2)
これは、副作用と関数型プログラミングを混ぜると起こることです。
関連
-
任意波形を生成してtxtで保存するためのPython実装
-
[解決済み】ImportError: sklearn.cross_validation という名前のモジュールがない。
-
[解決済み】 'numpy.float64' オブジェクトは反復可能ではない
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] リストが空かどうかを確認するにはどうすればよいですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
opencvとpillowを用いた顔認証システム(デモあり)
-
Python 人工知能 人間学習 描画 機械学習モデル作成
-
Pythonコードの可読性を向上させるツール「pycodestyle」の使い方を詳しく解説します
-
pyCaret効率化乗算器 オープンソース ローコード Python機械学習ツール
-
Python LeNetネットワークの説明とpytorchでの実装
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】Pythonスクリプトで「Expected 2D array, got 1D array instead: 」というエラーが発生?
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】Python: SyntaxError: キーワードは式になり得ない
-
[解決済み】NameError: 名前 'self' が定義されていません。