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
次に、モジュールでfrom module importで読みます.
1
2
3
4
5
6
7
別のモジュールに次のように書きます.
1
2
3
4
5
6
7
8
9
10
それから、先に書いて、後で読んで、書いた内容が有効かどうかを見ます.
1
2
3
4
5
6
7
8
9
10
結論はありません.原因は:
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
したがって、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
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