2


1

python 2.5にはTclのuplevelコマンドと同等のものがありますか?

pythonにはTclのuplevelコマンドに相当するものがありますか? 知らない人のために、「uplevel」コマンドを使用すると、呼び出し元のコンテキストでコードを実行できます。 Pythonでの表示方法は次のとおりです。

def foo():
    answer = 0
    print "answer is", answer # should print 0
    bar()
    print "answer is", answer # should print 42


def bar():
    uplevel("answer = 42")

ただし、変数を設定するだけではないため、辞書を変更するだけのソリューションを探しているわけではありません。 どんなコードでも実行できるようにしたい。

2 回答


3


一般に、あなたが尋ねることは不可能です(あなたが間違いなく期待する結果で)。 たとえば、「任意のコード」が「x = 23」であると想像してください。 「呼び出し元で」このコードを実行する黒魔術的な方法を見つけたと仮定すると、これは新しい変数 `x`を呼び出し元のローカル変数セットに追加しますか? いいえ-Pythonコンパイラによって実行される重要な最適化は、 `def`の実行時に、ローカル変数の正確なセット(割り当てられる、またはバインドされるすべてのベアネーム)を一度に定義することです関数の本体)、およびこれらのベアネームへのすべてのアクセスと設定を、スタックフレームへの非常に高速なインデックスに変換します。 (その重要な最適化を体系的に無効にします 可能なすべての呼び出し元の先頭に「exec」を置くことで、結果としてシステムのパフォーマンスがフロア全体でクラッシュするのを確認できます)。

_Except_を呼び出し側のローカルベアネームに割り当て、 localsでコードを実行し、theglobals`がおおよそ必要なことを行います。また、 inspect`モジュールを使用すると、呼び出し元のローカルおよびグローバルを半合理的な方法で取得できます(これまでのところ)ディープブラックマジック(同僚に本番コードで実行されることを示唆するようになります)は、それを「半合理的」と呼ぶのに値しない賞賛で称賛されることがあります;-)。

ただし、「任意のコードを実行できるようにしたい」と指定します。そして、_that_明確な仕様に対する唯一の解決策(そして、答えが簡単になるほど正確であることに感謝します!):それから、異なるプログラミング言語を使用します。


1


サードパーティのライブラリはPythonで書かれていますか? はいの場合、独自の実装で実行時に関数「foo」を書き換えて再バインドできます。 そのようです:

import third_party

original_foo = third_party.foo
def my_foo(*args, **kwds):
    # do your magic...
    original_foo(*args, **kwds)
third_party.foo = my_foo

モンキーパッチはフレームローカルを書き換えるよりもやや良いと思います。 ;)