下面是从理查德·琼斯的博客一些代码:

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
有帮助吗?

解决方案

这里有一种方法:

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块,这就是为什么我添加到两个主要的本地函数的with应该忽略。我不是很满意这个解决方案,这看起来有点复杂的100%,但我无法得到平等对待的正确测试与任何==is,所以我使出这个相当复杂的方法。

我还添加了一个循环(以更强烈的肯定使前defs /中/后正在妥善处理)和类型检查和函数调用,以确保testing权化身是用户确切的一个(一切似乎很好地工作) - 当然,因为只有书面作品,如果defwith是调用没有参数的函数的代码,就不难与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