pythonのfrom module import*のピット

4397 ワード

pythonのfrom module import*のピット
from module import*moduleのメンバーをすべて現在のglobal namespaceに導くとアクセスが便利になります.もちろん、python styleは、name conflictを引き起こす可能性があるため、一般的には推奨されません.
しかし、もう一つの問題があります.変数を修正したと思っていますが、from module import*に更新されていません.非常に危険です.プログラムが正常に動作する可能性があります.結果が間違っているだけで、productionに着いてから発見されるのは惨めです.
例を挙げます.
baseモジュールでいくつかの変数を定義しました.
1
2
3
4
5
6
7
8 # reference data type class Demo:   def __init__( self , name):    self .name = name demo = Demo( 'Demo' )
  # primitive type foo = 1
次に、モジュールでfrom module importで読みます.
1
2
3
4
5
6
7 from base import * def read():      print 'reference data id: ' + str ( id (demo))      print 'reference data value : ' + demo.name
       print 'primitive data id: ' + str ( id (foo))      print 'primitive data value: ' + str (foo)
別のモジュールに次のように書きます.
1
2
3
4
5
6
7
8
9
10 import base
  def write():   print "
Original:"
  print "Original reference data id: " + str ( id (base.demo))   base.demo.name = "Updated Demo" # this will reflect that change   #base.demo = base.Demo("Updated Demo") # this won't relfect the change   print "Original data id: " + str ( id (base.foo))   base.foo = 1000   print "Original data id after assignment: " + str ( id (base.foo))
それから、先に書いて、後で読んで、書いた内容が有効かどうかを見ます.
1
2
3
4
5
6
7
8
9
10 import read import write
  print "before write" read.read()
  write.write()
  print "
after write"
read.read()
結論はありません.原因は:
from module importを使用すると、copyはreferenceまたはpointerで、メモリ、var、moduleを指しています.varはmoduleを変更すると同じメモリを指します.varの場合、実際には別のメモリを指しています.varとmoduleです.varは異なるメモリを指しているので、module.varの値が変わったのか、varは元のメモリを指しているのか、元の値はobjectに対して、理解しやすいので、objectの値を直接変更することができます.これは有効ですが、別のobjectを指すと無効になります.primitiveタイプでは、inplaceが既存のメモリを変更するのではなく、値を割り当てるたびに異なるメモリアドレスを指すため、同じ理屈です.これは簡単に検証できます.
1
2
3
4
5
6
7
8
9 In [ 1 ]: a = 10
  In [ 2 ]: id (a) Out[ 2 ]: 20429204
  In [ 3 ]: a = 100
  In [ 4 ]: id (a) Out[ 4 ]: 20430108
したがって、quick and dirtyのスクリプトでない限り、from module import*を使用しないことをお勧めします.
例:https://github.com/baiyanhuang/blog/tree/master/arena/python/from_module_import
回転:http://www.jb51.net/article/52412.htm