正確ではありません。グローバルが浅くコピーされているのは間違いありませんが、実際に見ているのはグローバルのスコープ(キーワードglobal
を使用しています)とPythonのモジュールレベルでの実際の動作です。代入(X = 2
)の直後にpdb.set_trace()
ファンクションf
の中に入れてこれを確認することができます。
$ python -m doctest foo.py
> /tmp/foo.py(18)f()
-> return X
(Pdb) bt
/usr/lib/python2.7/runpy.py(162)_run_module_as_main()
-> "__main__", fname, loader, pkg_name)
/usr/lib/python2.7/runpy.py(72)_run_code()
-> exec code in run_globals
/usr/lib/python2.7/doctest.py(2817)<module>()
-> sys.exit(_test())
/usr/lib/python2.7/doctest.py(2808)_test()
-> failures, _ = testmod(m)
/usr/lib/python2.7/doctest.py(1911)testmod()
-> runner.run(test)
/usr/lib/python2.7/doctest.py(1454)run()
-> return self.__run(test, compileflags, out)
/usr/lib/python2.7/doctest.py(1315)__run()
-> compileflags, 1) in test.globs
<doctest foo.f[1]>(1)<module>()
-> f()
> /tmp/foo.py(18)f()
-> return X
(Pdb) pp X
2
はい、値が実際に2
f
の範囲内ですが、のは、そのグローバルのを見てみましょう。現在のフレームとフレームの比較方法を見てみましょう。
(Pdb) id(globals())
140653053803048 # remember this number, and we go up a frame
(Pdb) u
> <doctest foo.f[1]>(1)<module>()
-> f()
(Pdb) id(globals())
140653053878632 # the "shallow" clone
(Pdb) X
1
(Pdb) c
ヘクタールああ、あなたは彼らが実際には同じものではないことを見ることができ、そしてグローバルがこのような理由のためのdoctestによって作成<doctest doc.f>
モジュール内があるのでX
は、確かに1
であり、変更されていないこと。続けましょう。
(Pdb) id(globals())
140653053803048 # hey look, is the SAME number we remember
(Pdb) u
> <doctest foo.g[0]>(1)<module>()
-> g()
(Pdb) id(globals())
140653053872960 # note how this is a different shallow clone
それでは、あなたが実際に見たことX
が本当にf
によってここにモジュールに変更したので、(それゆえg
が2
を返しますdoctestの内のグローバルがあなたの元に一つとして同じものはないということですが、 Doctestモジュールの浅いコピースコープには含まれていません)、元々はモジュールからコピーされましたが、その変更は基礎となるモジュールに反映されませんでした。これはglobal
キーワードがモジュールレベルではなくモジュールで動作するからです。