source

다른 모듈에서 모듈 변수를 변경하는 방법은 무엇입니까?

bestscript 2023. 7. 19. 22:49

다른 모듈에서 모듈 변수를 변경하는 방법은 무엇입니까?

이름이 붙은 패키지가 있다고 가정합니다.bar그리고 그것은 포함합니다.bar.py:

a = None

def foobar():
    print a

그리고.__init__.py:

from bar import a, foobar

그런 다음 다음 스크립트를 실행합니다.

import bar

print bar.a
bar.a = 1
print bar.a
bar.foobar()

제가 기대하는 것은 다음과 같습니다.

None
1
1

다음과 같은 정보를 얻을 수 있습니다.

None
1
None

누가 내 오해를 설명해 줄 수 있습니까?

은 사중입다니를 사용하고 .from bar import a.a가져오기 모듈의 전역 범위(또는 가져오기 문이 발생하는 범위)에서 기호가 됩니다.

새로운 할 때a당신은 단지 어떤 가치를 바꿀 뿐입니다.a실제 값이 아닌 점도 표시됩니다.를 .bar.pyimport bar__init__.py그리고 그곳에서 당신의 실험을 설정하여 수행합니다.bar.a = 1 여러분은 이식으로실, 은게수될것다니입정하제로런당신▁be다▁actually▁this▁modifying것니를 수정하게 될 것입니다.bar.__dict__['a']은 의 '실제' 값다입의 입니다.a이런 맥락에서

세겹로 조복데요한잡금으▁it요.bar.a = 1 변합니다경의 합니다.a라는 에서.bar에서 실제로 파생된 것입니다.__init__.py은 변지않다습니의 .a 그거foobar 때문에foobar는 실제 파일인 실제파저있습다니어에 살고 .bar.py설정할 수 있습니다.bar.bar.a당신이 그것을 바꾸고 싶다면요.

은 이은사위중하다니나입험용의것을 할 때의 위험 중 입니다.from foo import barimport은 진술: 그은갈니다집라것다로 나뉩니다.bar두 개의 기호로, 하나는 내부에서 전체적으로 볼 수 있습니다.foo그것은 원래 값과 범위에서 보이는 다른 기호를 가리키는 것으로 시작합니다.import문이 실행됩니다.기호가 가리키는 위치를 변경해도 표시된 값은 변경되지 않습니다.

이런 종류의 것들은 살인자입니다.reload인터렉티브 인터프리터의 모듈입니다.

한 점은 이 이질의한가문이있것다입다니는이프램로지그정된름문라는 것입니다.bar/bar.py:import bar▁either를 가져옵니다.bar/__init__.py또는bar/bar.py하느냐에 어떤 것을 .a이라bar.a.

작동 방식은 다음과 같습니다.

무슨 일이 일어나는지 이해하는 열쇠는 당신의 안에서 그것을 깨닫는 것입니다.__init__.py,

from bar import a

사실상과 같은 일을 합니다.

a = bar.a
# … where bar = bar/bar.py (as if bar were imported locally from __init__.py)

그리고새정다니합의)를 정의합니다.bar/__init__.py:a원하신다면)그러므로, 당신의from bar import a__init__.py 이름 바인름bar/__init__.py:a의 처음터끝지부.bar.py:a목적어)None) 이것이 당신이 할 수 있는 이유입니다.from bar import a as a2__init__.py이 경우, 당신이 두 가지를 모두 가지고 있는 것은 분명합니다.bar/bar.py:a고유 변수 이름bar/__init__.py:a2두 둘 다 (경우당의다두, 이우둘연히름은의변수신다둘▁(당▁(▁just▁be우히연▁of▁the▁happen▁variables,이▁casein▁two▁to▁names름은▁both)가 됩니다.a 다른 공간에 있습니다: 하지만그여다삽네니에스다이페스임:in.__init__.py,그들은 그렇다.bar.a그리고.a).

이제, 당신이 할 때

import bar

print bar.a

변에액고있습다니하스세수에 .bar/__init__.py:a)import bar.bar/__init__.py 수정하는 변수입니다(1로).변수의 내용을 건드리지 않았습니다.bar/bar.py:a그래서 당신이 나중에 할 때

bar.foobar()

당신이 부르는bar/bar.py:foobar()변수에 액세스할 수 있는a부터bar/bar.py아직은None(언제foobar()정의되고, 그것은 변수 이름을 완전히 묶습니다, 그래서.abar.py이라bar.py:a 어떤 도 아닌a모듈에 - 수가 수 - 변수 - 를 합니다.a변수)를 입력합니다. 그므로마막지러▁hence막.None산출량.

결론: 모호함을 피하는 것이 가장 좋습니다.import bar없는 것으로bar/bar.py)bar.__init__.py 디렉터리 makes 렉리토디리bar/이미 가져온 패키지를 사용하여 가져올 수도 있습니다.import bar).

달리 말하면,이러한 오해는 만들기가 매우 쉽다는 것이 밝혀졌습니다.는 Python 언어 참조에서 은밀히 정의됩니다. 기호 대신 객체 사용입니다.저는 파이썬 언어 참조가 이것을 더 명확하고 덜 희소하게 만들 것을 제안하고 싶습니다.

from폼은 모듈 이름을 바인딩하지 않습니다. 즉, 식별자 목록을 검토하고 (1) 단계에서 찾은 모듈에서 각각의 식별자를 찾고 로컬 네임스페이스의 이름을 이렇게 찾은 개체에 바인딩합니다.

단,

가져올 때 가져온 기호의 현재 값을 가져와 정의된 대로 네임스페이스에 추가합니다. 참조를 가져오는 것이 아니라 값을 실제로 가져오는 것입니다.

업데이트된 값인 업얻위값기해을된트의 .i해당 기호에 대한 참조를 포함하는 변수를 가져와야 합니다.

다시 말해, 수입은 다음과 같지 않습니다.import JAVA에서external C/C++로 선언합니다.usePERL의 절입니다.

Python에서 다음 문장을 사용합니다.

from some_other_module import a as x

는 K&R C의 다음 코드와 더 유사합니다.

extern int a; /* import from the EXTERN file */

int x = a;

(caveat: 파이썬의 경우, "a"와 "x"는 본질적으로 실제 값에 대한 참조입니다: INT를 복사하는 것이 아니라 참조 주소를 복사하는 것입니다.)

언급URL : https://stackoverflow.com/questions/3536620/how-to-change-a-module-variable-from-another-module