다른 모듈에서 모듈 변수를 변경하는 방법은 무엇입니까?
라는 패키지가 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.py
직접 가져 와서을 설정하여 실험을 수행하십시오 . 이렇게하면 실제로이 컨텍스트에서 '실제'값을 수정 하게 됩니다.import bar
__init__.py
bar.a = 1
bar.__dict__['a']
a
세 개의 레이어로 약간 복잡하지만 실제로에서 파생 된 라는 모듈 bar.a = 1
의 값을 변경합니다 . 의이 값을 변경하지 않는 그 때문에보고 실제 파일에서의 삶 . 변경하려면 설정할 수 있습니다.a
bar
__init__.py
a
foobar
foobar
bar.py
bar.bar.a
이것은 문장 의 from foo import bar
형태 를 사용할 때의 위험 중 하나입니다 import
. 그것은 bar
두 개의 기호로 분할 됩니다. 하나 foo
는 원래 값을 가리 키기 시작하는 전역에서 볼 수 있고 import
문장이 실행되는 범위에서 볼 수있는 다른 기호 입니다. 심볼이 가리키는 위치를 변경해도 가리키는 값도 변경되지 않습니다.
이런 종류의 것들은 reload
인터랙티브 인터프리터에서 모듈을 시도 할 때 킬러 입니다.
이 질문에 어려움 중 하나는 소스라는 이름의 프로그램을 가지고있다 bar/bar.py
: import bar
수입하거나 bar/__init__.py
또는 bar/bar.py
이 조금 성가신를 추적 할 수있는 완료 위치에 따라 a
입니다 bar.a
.
작동 방식은 다음과 같습니다.
무슨 일이 일어나는지 이해하는 열쇠는 당신의 __init__.py
,
from bar import a
사실상 다음과 같은 일을한다
a = bar.a # … with bar = bar/bar.py (as if bar were imported locally from __init__.py)
and defines a new variable (bar/__init__.py:a
, if you wish). Thus, your from bar import a
in __init__.py
binds name bar/__init__.py:a
to the original bar.py:a
object (None
). This is why you can do from bar import a as a2
in __init__.py
: in this case, it is clear that you have both bar/bar.py:a
and a distinct variable name bar/__init__.py:a2
(in your case, the names of the two variables just happen to both be a
, but they still live in different namespaces: in __init__.py
, they are bar.a
and a
).
Now, when you do
import bar
print bar.a
you are accessing variable bar/__init__.py:a
(since import bar
imports your bar/__init__.py
). This is the variable you modify (to 1). You are not touching the contents of variable bar/bar.py:a
. So when you subsequently do
bar.foobar()
you call bar/bar.py:foobar()
, which accesses variable a
from bar/bar.py
, which is still None
(when foobar()
is defined, it binds variable names once and for all, so the a
in bar.py
is bar.py:a
, not any other a
variable defined in another module—as there might be many a
variables in all the imported modules). Hence the last None
output.
To put another way: Turns out this misconception is very easy to make. It is sneakily defined in the Python language reference: the use of object instead of symbol. I would suggest that the Python language reference make this more clear and less sparse..
The
from
form does not bind the module name: it goes through the list of identifiers, looks each one of them up in the module found in step (1), and binds the name in the local namespace to the object thus found.
HOWEVER:
When you import, you import the current value of the imported symbol and add it to your namespace as defined. You are not importing a reference, you are effectively importing a value.
Thus, to get the updated value of i
, you must import a variable that holds a reference to that symbol.
In other words, importing is NOT like an import
in JAVA, external
declaration in C/C++ or even a use
clause in PERL.
Rather, the following statement in Python:
from some_other_module import a as x
is more like the following code in K&R C:
extern int a; /* import from the EXTERN file */
int x = a;
(caveat: in the Python case, "a" and "x" are essentially a reference to the actual value: you're not copying the INT, you're copying the reference address)
참고URL : https://stackoverflow.com/questions/3536620/how-to-change-a-module-variable-from-another-module
'developer tip' 카테고리의 다른 글
git push origin HEAD는 무엇을 의미합니까? (0) | 2020.09.22 |
---|---|
Ruby의 다른 괄호는 무엇을 의미합니까? (0) | 2020.09.22 |
Node JS 오류 : ENOENT (0) | 2020.09.22 |
Windows 및 .NET에서 Memcached (0) | 2020.09.22 |
파이썬 3에서 바이트에 대해 b '접두사없이 억제 / 인쇄 (0) | 2020.09.22 |