2010-04-07 2 views
2

저는 파이썬 스코핑에 대한 이해가 부족한 것 같습니다. 아마도 당신이 도울 수 있습니다."library"메서드의 범위

배경 : 내 모듈 (들)의 "자가 테스트"를 수행하기 위해

if __name__ == "__main__" 

구조를 사용하고
. 각 자체 테스트는 모듈을 개발할 때 다양한 공용 메소드를 호출하고 시각적 검사를 위해 결과를 인쇄합니다.

는 것 "퍼디"을 유지하고 관리하기 위해, 나는 방법의 테스트를 단순화하는 작은 방법을 만들었습니다 호출

def pprint_vars(var_in): 
    print("%s = '%s'" % (var_in, eval(var_in))) 

때와

foo = "bar" 

호출 pprint_vars :

pprint_vars('foo') 

인쇄물 :

foo = 'bar' 

모두 좋고 좋습니다.

문제 문 : 그냥 키스 행복하지
, 나는 'debug_tools.py'라는 별도의 파일로 내 편리한 - 멋쟁이 'pprint_vars'방법을 이동하고 간단하게 가져올 수있는 뇌 이슬비가 있었다 'debug_tools'내가 원하는 때마다 'pprint_vars'에 대한 액세스.

여기가 사별됩니다. 내가

import debug_tools 

foo = bar 
debug_tools.pprint_vars('foo') 

은 마법과 인쇄 작업을 계속 기대 :

NameError: name 'some_var' is not defined 

불합리한 신념 : 대신

foo = 'bar' 

를, 그것은 나를 맞이
내가 생각 (분명히 실수) import는 가져온 메소드를 코드와 "인라인"(inline) 넣습니다. 따라서 변수 범위 지정 규칙은 메소드가 인라인으로 정의되었습니다.

도움을 주셔서 감사합니다.
누군가 내 범위 조정에 대한 이해를 잘못 교정 할 수 있습니까?

덕분에, JS

+0

정확히 동일한 코드를 올렸습니까? 'foo ='bar ''가 아닌가? 그리고 오류 메시지에서''some_var ''을 찾을 수 없습니다. –

+0

당신이 맞습니다, 펠릭스. 내 사과. 나는 (잘하면) 오류를 정정했다. –

+0

'__name__' 관용어는 대개 '__name__' == "__main__":'으로 작성되며 동등성을 테스트합니다. 그것은 __in__ 연산자를 사용하는 것처럼 작동합니다. 포함 시키려고 테스트하지만 우연히 발생합니다. – Todd

답변

2

각 파일은 자신의 네임 스페이스입니다 : - 글로벌지역 - 당신이 당신의 소스를 평가하기 위해 컨텍스트로 지정할 수 있습니다

2

"글로벌 범위는"실제로 파이썬에 존재하지 않습니다. 일반적으로 "전역 범위"라고하는 것은 실제로 모듈 범위입니다. 즉, 모듈 수준에서 정의 된 이름입니다. 함수를 다른 모듈에 넣으면 해당 모듈 범위가 변경됩니다.파이썬에서

print("%s = '%s'" % (var_in, eval(var_in, globals()))) 
+0

내 목표를 달성하기 위해 선호하는 방법으로 무엇을 제안 하시겠습니까? –

+0

다양한'inspect.* 호출자의 프레임을 얻기 위해 * frame *()'함수를 호출 한 다음 프레임의'f_locals' 속성에 접근하여 지역 정보를 얻습니다 :'inspect.getouterframes (inspect.currentframe()) [1] [0] .f_locals [var_in] ' –

0

평가는 두 개의 선택적 매개 변수를 받아들입니다.

  1. 로컬 변수
  2. (모듈) 전역 변수
  3. 내장 매크로

(즉 포착 변수 또는 클로저를 포함하는) 함수가 호출 될 때, 다음과 같은 순서로 그 변수를 해결 호출자를 프레임 목록으로 탐색하려면 (통역사 전용) inspect 모듈을 사용할 수 있습니다. 프레임은 지역 주민, 전역, 내장 매크로 및 상위 프레임을 알고 있기 때문에, 당신은 (디버깅에만 사용하십시오)이 같은 발신자의 눈을 통해 인터프리터를 '볼'수

import inspect 
def log_var(name): 
    f = inspect.currentframe().f_back 
    if name in f.f_locals: 
     print "local `%s` = %r" % (name, f.f_locals[name]) 
    elif name in f.f_globals: 
     print "global `%s` = %r" % (name, f.f_globals[name]) 
    elif name in f.f_builtins: 
     print "builtin `%s` = %r" % (name, f.f_builtins[name]) 
    else: 
     print "`%s` not found" % name 
+0

'var_in'이 완전히 다른 알 수없는 모듈에 있어야한다고 가정하면 도움이되지 않습니다. –

1

내가 지역 주민을 전달 추천() 그래서 같은 기능 ...

def pprint_var(var_name, D): 
    print "%s = %r" % (var_name, D[var_name]) 

... 당신이 원하지 않는 경우

pprint_var(var_name, locals()) 

, 당신은 동일한 작업을 수행하기 위해 검사 모듈 또는 sys._getframe을 사용할 수 있습니다에 다른 것이 제안한 것처럼 디.

0

기본 문제는 Python이 단순한 객체의 경우 이라는 의미가 없다는 것입니다. 메서드, 클래스 등 예, 간단한 개체의 경우 아니오. 내가 어떤 프로젝트에 'ppvar'를 포함하는 파일을 가져오고 그것을 호출 할 수

ppvar(var_name): 
    print("%s = '%s'", var_name, $var_name) 

: 그래서 변수를 특징으로 언어

내 'ppvar'기능이 (의사 코드)과 같을 것 그것은 본질적으로 내 코드에 "인라인 될"것입니다.

이것은 "기능 프로그래밍"개념 일 가능성이 높으며 객체 지향 접근 방식에는 적합하지 않습니다.

모든 언어에는 더하기 및 빼기가 있습니다. 모든 언어에는 그것이 떨어지는 몇 가지 "단순한"것들이 있습니다. 같은 것을 할 수있는 것 :

print("%s = '%s'" % (var.__name__, var) 

파이썬에서는 (아직은) 작동하지 않는 것입니다. 오 잘.