문제

다음은 몇 가지 코드입니다 Richard Jones의 블로그:

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

내 질문은 : 도대체 어떻게 이것을 했습니까? Context Manager가 With Block 내부의 범위에 어떻게 액세스 할 수 있습니까? 다음은 이것을 알아 내기위한 기본 템플릿입니다.

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 식별 된 것입니다 (모든 것이 잘 작동하는 것 같습니다) - 물론 작성된 코드는 다음과 같은 경우에만 작동합니다. 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