2010-12-14 2 views
10

나는는 수입 * 사이 XXX 가져 오기 *의 차이를 확인하는 것은

import foo 

from foo import * 

글로벌 회원에 다른 효과를 가지고 있다는 것을 발견 놀랐습니다. 내 실험이 올바른 행동인지 확인하고 싶었습니다.

첫 번째 예에서 모듈 foo의 멤버를 변경하면 foo를 가져 오는 모든 코드가 반영됩니다. 그러나 나중에 해당 멤버를 변경하면 가져온 파일에만 영향을 미칩니다. 다시 말하면, 이후의 접근법을 사용하면 각 가져 오기 파일에 foo의 멤버 사본을 제공하게됩니다.

모든 파일에서 foo.x에 액세스 할 수 있고, 모든 파일에서 변경할 수 있으며, 변경 사항을 모든 파일 (모든 경우 true true)에 반영해야합니다.

답변

14

예, 관찰 결과가 정확합니다. 이것은 바인딩이 파이썬에서 작동하는 방식의 결과입니다.

하나가하는

import foo 

foo 모듈 foo를 참조하는 전역 이름이됩니다. 그럴 때

foo.bar = 7 

다음에 참조 번호와 객체 foo이로드됩니다. 그런 다음 7bar 속성에 저장됩니다.

다른 모듈이 foo을 가져 오면 sys.modules['foo']에서 개체를 가져 와서 수정 된 값을 가져옵니다. 하나 않으면

from foo import bar 

globals()['bar']foo.bar를 참조하도록 설정되어있다. 하나 나중에

bar = 7 

globals()['bar']을 수행 할 때 더 이상 foo.bar하지만 참조 7의 사본을 참조하지 않습니다. 즉, 가져 오기 모듈의 전역 범위에서 원래 바인딩은 간단히 대체됩니다.

첫 번째 예제에서는 sys.modules에 저장된 개체의 특성을 수정하고 가져온 모든 모듈에 공통으로 적용됩니다. 두 번째 예에서는 가져 오기 모듈의 전역 범위를 수정합니다.

하나가 수정을 다음 전역 참조하지만 을 덮어하지 때문에 하나는 그 변화 다른 가져 오기 모듈에 전달 될 그런

from foo import fobaz 
fobaz.foobar = 7 

의 라인을 따라 뭔가를했다면 객체가 가리키는 속성. 따라서 기본적으로 전역 바인딩을 덮어 쓰지 않는 한 변경 가능한 개체를 수정할 수 있어야합니다.

저는이 점이 여러분이 파이썬에서 진정한 글로벌 환경에 깨끗하게 도달 할 수 있다고 생각합니다. 언어로서, 그것은 네임 스페이스를 매우 중요하게 생각합니다.

+0

와우 나는 이것을 몰랐다. 좋은 대답. – invert

4

글로벌 변수가 일반적으로 나쁜 것으로 간주된다는 것을 고려할 때, 나는 "진정한 글로벌 변수"가 매우 나쁜 것임을 의심합니다.

유사한 동작을 얻는 또 다른 방법 중 하나는 싱글 톤 개체에서 클래스 범위 특성을 사용하여이를 가져 오는 것입니다. 그런 다음 "전역 변수"를 가져 오는 위치가 더 명확합니다.

+0

좋은 지적입니다. 답해 주셔서 감사합니다. –

관련 문제