8

「a!」を出力するだけの単一の関数を持つ Python モジュールを作成しました。Python インタープリターを開き、モジュールを 2 つの異なる構文でインポートしました

>>> import a
>>> from a import func
>>> func()
a!
>>> a.func()
a!

この時点で、 func を変更して別のものを出力し、再度評価します

>>> func()
a!
>>> a.func()
a!

モジュールがリロードされていないため、これは当然のことです。次に、モジュールをリロードし、両方の機能が更新されることを期待しましたが、次のようになりました。

>>> reload(a)
<module 'a' from 'a.py'>
>>> a.func()
aasd!
>>> func()
a!

a.func だけが更新されるようです。Python は同じモジュールのインスタンスを 1 つだけ保持しているといつも思っていましたが、現在は 2 つあるようです。私の主張を検証するためにさらにテストを行い、モジュールの最上位に print ステートメントを追加し、インタープリターを再起動して再度インポートしました。

>>> import a
module imported
>>> import a
>>> from a import func

「モジュールがインポートされました」が2回表示されると思っていたので、これはさらに混乱します。私が行った 3 番目の実験は、グローバル変数の実験でした。

>>> import a
module imported
>>> from a import GLOBAL_VAR
>>> GLOBAL_VAR = 5
>>> a.GLOBAL_VAR
1
>>> GLOBAL_VAR
5
>>> GLOBAL_VAR is a.GLOBAL_VAR
False

モジュールのインスタンスは 1 つですが、内部のオブジェクトのインスタンスは異なるのでしょうか? このような動作でGevent のモンキー パッチを実装するにはどうすればよいでしょうか?

4

4 に答える 4

8

モジュールは、インポートされると、単なる別の python オブジェクトです。したがって、次の例を見ると、結果はまったく驚くべきものではありません。

x = SomeObject()
x.y = 1
a = x.y
x.y = 2
print(a) #a is still 1, not 2

すると、インポートされたもの(パッケージ/モジュール/クラス/何でも)への参照を保持するfrom module import name変数が現在の名前空間に作成されます。nameこれは、次のシンタックス シュガーです。

import module
name = module.name

をリロードすると、明らかに参照保持がmodule更新されません。name

2 番目の実験に関してはsys.modules、インポート後にモジュールがキャッシュされます。後続のインポートはキャッシュを利用します。したがって、モジュール レベルに直接あるすべてのコードはprint、最初のインポートでのみ実行されます。

于 2013-12-16T08:10:59.073 に答える
2

モジュールをリロードすると、その中のすべての関数が現在のモジュールにリロードされます。ただし、モジュールから特定の関数をインポートすると、現在のモジュールに対してローカルになります。したがって、一方を変更しても他方には影響しません。

これをチェックしてください:

import math
from math import factorial
print locals()

print id(math.factorial), id(factorial)

math.factorial, factorial = 0, 1
print id(math.factorial), id(factorial)

reload(math)
print id(math.factorial), id(factorial)

from math import factorial
print id(math.factorial), id(factorial)

出力

{'__builtins__': <module '__builtin__' (built-in)>,
 '__file__': '/home/thefourtheye/Desktop/Test.py',
 '__package__': None,
 'factorial': <built-in function factorial>, # Factorial is in the local context
 '__name__': '__main__',
 '__doc__': None,
 'math': <module 'math' (built-in)>}
39346504 39346504
33545712 33545688
39346504 33545688
39346504 39346504

idCPython 実装のメモリ内のオブジェクトのアドレスを出力します

于 2013-12-16T07:53:26.150 に答える