2

次の 2 つのスクリプトがあります。

#imptee.py
foo = "abc"

def show():
    print "foo from imptee:",foo

#impter.py:

#!/usr/bin/env python

from imptee import *

show()

foo = 123
 
print "foo from impter:",foo
show()

impter.py を実行すると、次の結果が得られます。

imptee からの foo: abc

impter からの foo: 123

imptee からの foo: abc

変数 foo に 123 を割り当てた後、show() が 123 ではなく 'abc' を出力する理由がわかりません。「from imptee import *」の後、foo と show() は現在グローバル名前空間にあり、ローカル名前空間はありません。検索順序は、ローカルの名前空間、グローバルの名前空間、組み込みの名前空間の順である必要があることは理解しています。それで、それはなぜですか?誰か手を貸してくれませんか?THX!

4

3 に答える 3

3

Python で「グローバル名前空間」と呼ばれるものは、実際にはモジュールの名前空間です。各モジュールには 1 つあり、それらは独立しています。*したがって、 from からインポートすると、オブジェクト参照が fromにimpteeコピーされます。事後でも独自の名前空間があり、関係なく参照されています。imptee__main__impteeshow()

于 2012-06-09T19:18:19.947 に答える
1

モジュールには個別の名前空間があります。あるモジュールから別のモジュールにインポートする場合、ソース モジュールから値 (通常は関数ですが、この場合はリテラル "abc") をインポートし、それらを宛先モジュールの名前に割り当てます。

を行うfrom imptee import *と、ソース モジュールにあったのと同じ名前に割り当てられますが、ソース モジュール内のポインターは実際には変更されません。名前が重複しているだけです。

インポート後に宛先モジュールの割り当てを変更しても、ソース モジュールでは何も変更されません。名前が同じように見えても、それらは別のポインターであり、別のものを指すことができるからです。

import impteeこれを行ってから手動で値を割り当てた場合、これはより明確になる可能性があります: foo = imptee.foo。その後、後で を実行します。foo = 123目的のモジュールの foo の値は変更されていますが、ソース モジュールの同様の名前のポインターの値は変更されていないことは理にかなっています。

于 2012-06-09T19:20:34.840 に答える
1

ステートメントfrom imtee import *は (ほぼ) と同じでfrom imptee import fooあり、これも (ほぼ) と同じだからimport imptee; foo = imptee.fooです。同じ値を 2 つの変数に代入してから、それらの変数の 1 つを変更しても、他の変数の値は変更されないのと同じ理由で、foo変更されません。imptee

>>> a = "hello"
>>> b = a
>>> a
'hello'
>>> b
'hello'
>>> b = 'world'
>>> a
'hello'
>>> b
'world'

さらに、他の回答が指摘しているように、「グローバル」名前空間は実際には「モジュールに対してグローバル」であり、「すべてのモジュールに対してグローバル」ではありません。他のモジュールのグローバル変数は、モジュールをインポートしてから対応する属性を設定することで変更できます: import imptee; imptee.foo = "bar".

于 2012-06-09T19:16:54.947 に答える