python importとfrom import

2080 ワード

importとfrom importは、他のモジュールを現在のモジュールにインポートします.最初はimportとfrom importの唯一の違いは、from importがモジュール名を少なく書くことができることだと思っていました.from XX importは現在の名前空間を汚染しますが、それだけのようです.しかし、実はfrom importにはかなり深刻な罠があります.例として、
#a.py
test = 2
print 'in a'
#b.py
from a import *
print test
test = 3
from c import *
print test
#c.py
from a import *
print test
test = 4

結果:
python b.py
in a
2
2
4

コードを次のように変更します.
#a.py
test = 2
print 'in a'
#b.py
import a
print a.test
a.test = 3
import c
print c.a.test
#c.py
import a
print a.test
a.test = 4

結果:
python b.py
in a
2
3
4

もし、a.pyのtest=2をtest=[2]に変更し、後でtestの変更をtest[0]の変更に変更した場合、importとfrom importの結果は完全に一致していることがわかります.
以上の分析により.基本的には、1 importまたはfrom importを繰り返しても2 importとfrom importを1回だけ作用する作用メカニズムが全く異なる3 importのメカニズムは、ターゲットモジュール内のオブジェクトを現在のモジュールに完全に導入するが、新しい変数名4 from importを導入しないメカニズムは、新しい変数名を導入する形式であり、ターゲットモジュールのオブジェクトの参照を新しい変数名にコピーする方法で現在のモジュールに導入
このような記述は抽象的であるかもしれないが、上記の例によれば、1 importを使用する場合、a.test変数という名前のものが1つしか存在せず、bモジュールでもcモジュールでも2 from importを使用する場合、bモジュールには新しい変数b.testが存在し、開始時にb.test=a.test(これらは共に同じオブジェクトを指す)が存在し、付与が発生すると、b.testは新しいオブジェクトを指しますが、a.testは元のオブジェクトを指します.具体的には、(1)初期にaにa.test変数が存在し、1つの整数オブジェクト‘2’(2)がb.pyを実行するときfrom a import*の実行を指す.新しい変数名b.test,b.test=a.testが導入されたことに相当する.この場合、b.testとa.testはいずれも整数オブジェクト‘2’(3)の後の付与操作(test=3)を指し、b.test=3となる.b.testが整数オブジェクト'3'を指し、a.testが整数オブジェクト'2'(4)を指してfrom c import*を実行し続ける場合、c.pyに入り、cモジュールでfrom a import*を実行すると、新しい変数名c.test、c.test=a.testが導入され、これらはいずれも整数オブジェクト'2'を指し、その後の付与操作(test=4)によりc.test=4となり、現在、c.testは整数オブジェクト'4'を指し、一方、a.testは整数オブジェクト'2'(5)を指してb.pyに戻る.b.testはすでに存在するため、新しい変数を引き付けるのではなく、直接b.test=c.testを実行する.この場合、b.testは整数オブジェクト'4'の最終的な結果を指し、a.testは'2'、b.testは'4'、c.testは'4'3を指し、testがlistになったとき、b.test[0]の修正は、b.test自体の変化を引き起こさず、言い換えれば、b.testとa.testは同じオブジェクトを指していますが、このオブジェクトの内部は変更されています.
まとめ:1 from importは危険ですが、その作用メカニズムを理解していない場合は、慎重に2メカニズムを知っていても、同じように慎重に使用します(元の時間2015-03-03)