2014-12-06 1 views
3

는 파이썬에서 무언가를 평가 후면 경우상단 스택 프레임에서 locals() 및 globals()를 가져올 수 있습니까?

eval("a + b") 

이것은 현재 범위 (지역 주민과 전역 두)를 사용하여 식을 평가합니다.

내가 개발중인 것은 표현식을 "나중에"평가해야한다는 것입니다. 이 단어는 현재 범위 (예 : locals()globals())를 유지하기를 원함을 나타냅니다. 하지만 이러한 값을 투명하게 전달하거나 상위 스택 프레임에서 가져 오려고합니다. (실제로,이 하나 존재)이 구현을 고려

def __eval(self, expr): 
    if isinstance(expr, (list, tuple, set, frozenset, dict, Expression)): 
     return Expression.eval(expr, self) 
    elif callable(expr): 
     try: 
      return expr(self) 
     except (AttributeError, IndexError, KeyError, TypeError): 
      return UNDEFINED 
    else: 
     try: 
      return eval(expr, {}, {'self': self}) 
     except (AttributeError, IndexError, KeyError, TypeError): 
      return UNDEFINED 

를 다음과 같이 구현 설명 : 내가 표현 개체를 사용하는 경우

  • (I 실제로 같은 객체를 개발), 다음 나는 그런 표현을 평가 현재 개체를 사용하여 (결국이 함수는 메서드입니다). 이 부분은 도움이 필요 없으며, 완전히 개발되었습니다.
  • 호출 가능 객체를 사용하는 경우 호출 가능 객체 (예 : 람다 표현식)를 실행합니다.
  • 문자열을 사용하는 경우 파이썬 표현식이되며 호출 시간이 locals()globals() 인 이러한 평가를 수행해야합니다.

    o._O__eval("self.a + self.b", globals(), locals()) 
    #THIS WOULD REQUIRE to alter the method to allow two additional dict parameters 
    #NO, I will not call this function directly, but lets follow the example 
    

    하지만 명시 적으로 전달 사용자없이 globals()locals 등을 얻고 eval에 같은 값을 사용하고 싶습니다 :

은 내가 명시 적으로 호출 할 수 있습니다 알고 있습니다.

질문 : 상단 스택 프레임에서 locals()globals()을 얻을 수 있습니까?

+2

이 디자인에서 "모든 사람이 당신과 똑같은 일을하고 싶다면 어떻게해야합니까? 아르?" 문제. 즉, 원하는 것을 얻은 다음'__eval'을 호출하는 다른 편리한 함수를 작성하고 싶다고 가정 해 봅시다. "스택 프레임이 아니고 다른 레벨을 계속 올라가고 있지 않습니까?"라고 어떻게 말해야합니까? –

+0

당신이 감히 'scope ['$ eval '] ("a + b")를 호출한다면 - 여기서 설명하지 않기 때문에 - __eval을 호출하는 실제 방법이 있습니다 (예, AngularJS 포트의 일종입니다). 파이썬이지만 부분적으로) 호출 시간의 어휘 범위를 사용하게 될 것입니다 (어휘 범위는 현재 $ scope 객체를 가리키는 'self'를 갖는 추가 처리가 있습니다). 이제 작동합니다 :). –

+0

그러나이 이상한 사용 사례를 요청했지만 대부분 필요하지는 않습니다. $ eval은 항상 $ watch 호출 내에서 호출됩니다 (결국 AngularJS $ rootScope 포트입니다). –

답변

3

당신은 정말 globals()locals() 전달 고려해야합니다

def __eval(self, expr, eval_globals=None, eval_locals=None): 
    if eval_globals is None: 
     eval_globals = globals() 
    if eval_locals is None: 
     eval_locals = eval_globals() 

을하는 당신을위한 옵션이없는 경우 에 액세스 sys._getframe() function와 상위 프레임 및 지역 주민과 전역 해당 프레임의 속성입니다.

def __eval(self, expr, eval_globals=None, eval_locals=None): 
    call_frame = sys._getframe(1) 
    eval_globals, eval_locals = call_frame.f_globals, call_frame.f_locals 
+0

지금 테스트 중입니다. :) ... –

관련 문제