这是Richard Jones' Blog的一些代码:

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

我的问题是:他到底是怎么做到的?上下文管理器如何访问with块内的范围?这是一个试图弄清楚这一点的基本模板:
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中添加了两个主要的本地函数的原因。我对这个解决方案不太满意,该解决方案看起来有点复杂,但是我无法使用==is正确进行相等性测试,因此我采用了这种相当复杂的方法。

我还添加了一个循环(以确保在正确地处理之前/之内/之后的def)和一个类型检查和函数调用,以确保testing的正确化身已被识别(所有内容)似乎工作正常)-当然,仅当def中的with用于无需参数即可调用的函数时,编写的代码才有效,因此不难获得带有inspect的签名以对抗该问题(但是由于我正在调用仅是为了检查是否标识了正确的函数对象,我对最后的改进并不感到烦恼;-)。

关于python - 查找用: Block定义的函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1255914/

10-12 12:39
查看更多