質問

ここでリチャード・ジョーンズのブログのからいくつかのコードがあります:

with gui.vertical:
    text = gui.label('hello!')
    items = gui.selection(['one', 'two', 'three'])
    with gui.button('click me!'):
        def on_click():
            text.value = items.value
            text.foreground = red

私の質問は:一体彼はこれをやったのか?どのようにコンテキストマネージャは、ブロックと内部のスコープにアクセスすることができますか?ここではこれを理解しようとするための基本的なテンプレートです。

from __future__ import with_statement

class button(object):
  def __enter__(self):
    #do some setup
    pass

  def __exit__(self, exc_type, exc_value, traceback):
    #XXX: how can we find the testing() function?
    pass

with button():
  def testing():
    pass
役に立ちましたか?

解決

ここに1つの方法です。

from __future__ import with_statement
import inspect

class button(object):
  def __enter__(self):
    # keep track of all that's already defined BEFORE the `with`
    f = inspect.currentframe(1)
    self.mustignore = dict(f.f_locals)

  def __exit__(self, exc_type, exc_value, traceback):
    f = inspect.currentframe(1)
    # see what's been bound anew in the body of the `with`
    interesting = dict()
    for n in f.f_locals:
      newf = f.f_locals[n]
      if n not in self.mustignore:
        interesting[n] = newf
        continue
      anf = self.mustignore[n]
      if id(newf) != id(anf):
        interesting[n] = newf
    if interesting:
      print 'interesting new things: %s' % ', '.join(sorted(interesting))
      for n, v in interesting.items():
        if isinstance(v, type(lambda:None)):
          print 'function %r' % n
          print v()
    else:
      print 'nothing interesting'

def main():
  for i in (1, 2):
    def ignorebefore():
      pass
    with button():
      def testing(i=i):
        return i
    def ignoreafter():
      pass

main()

編集:コードもう少し伸ばし、...いくつかの説明を追加します:

__exit__で、発信者の地元の人々をキャッチするのは簡単です - トリッキー私はwithは無視すべき主な2つのローカルな機能を追加した理由です。のwithブロック、前にすでに定義されていたものを地元の人々を避けています。私は少し複雑に見えます。このソリューション、100%満足していないんだけど、私は==またはisのいずれかで正しいテスト平等を得ることができなかったので、私は、この複雑なアプローチに頼っています。

私もループを追加しました(/は、後に適切に処理されている範囲内/ defs前より強く確認します)と、型チェックと関数呼び出しは、確認するためにtestingの右の化身は、特定されています一つです(すべてが正常に動作するようです) - もちろん書かれたように、コードはdef内部withは、引数なしで呼び出し可能な機能のためであれば、それはそれに対して病棟にinspectで署名を取得することは難しいことではありません動作します(が、私はだので、唯一の右の関数オブジェクトが識別されていることを確認する目的のためにコールをやって、私はこの最後の微調整については気にしませんでした; - )

他のヒント

あなたの質問に答えるために、はい、それはフレームのイントロスペクションです。

しかし、私は同じことを行うために作成し構文は次のとおりです。

with gui.vertical:
    text = gui.label('hello!')
    items = gui.selection(['one', 'two', 'three'])
    @gui.button('click me!')
    class button:
        def on_click():
            text.value = items.value
            text.foreground = red

ここで私は(gui.buttonが同様に罰金であることを今私には見えるが)いくつかのパラメータとイベントの特定のボタンインスタンスを返すデコレータとしてbutton = gui.button('click me!', mybutton_onclickを実装します。

それは内省することなく実施することができるので、そのままでは

私はまたgui.verticalを残すでしょう。私はその実装についてはよく分からないんだけど、gui.direction = gui.VERTICALと他の人がそれらの座標を計算する際にそれを使用するように、それはgui.label()を設定することを含むことができる。

:私はこれを見たときに

さて、私は、構文をしようと思います

    with gui.vertical:
        text = gui.label('hello!')
        items = gui.selection(['one', 'two', 'three'])

        @gui.button('click me!')
        def button():
            text.value = items.value
            foreground = red

タグ(アイデアは、同様にラベルがテキストから作られてどのように、ボタンはテキストや機能から作られていることです)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top