分包导入或全路径差
Import from subpackage or full path difference
从不同的路径导入相同的 Python 模块似乎会导致创建两个不同的模块引用。
例如以下三个Python脚本。 Script1和Script2位于OuterPackage中,TestWithGlobals位于SubPackage中。
+ Root
|_+ OuterPackage
| - Script1
| - Script2
|_+ SubPackage
| - TestWithGlobals
脚本 1:
from OuterPackage.SubPackage import TestWithGlobals
import Script2
print TestWithGlobals.__name__
print TestWithGlobals.global_string
Script2.MakeStringBall()
print TestWithGlobals.global_string
和脚本 2:
from SubPackage import TestWithGlobals
print TestWithGlobals.__name__
def MakeStringBall():
TestWithGlobals.global_string = "ball"
最后是 TestWithGlobals 本身
global_string = "test"
现在,当 Script1 为 运行 时,输出如下:
SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
test
test
在 Script2 中将 from SubPackage
更改为 from OuterPackage.SubPackage
将导致 Script1 的不同输出:
OuterPackage.SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
test
ball
在 运行ning Script1.
之前将根目录附加到 pythonpath
为什么引用同一个模块时,Script1 和 Script2 的 TestWithGlobals 不同?这背后的原因是什么?
如果您按如下方式更改代码,它会告诉您更多发生的事情:
Script1.py
import sys
from OuterPackage.SubPackage import TestWithGlobals
print "In Script1", id(sys.modules['OuterPackage.SubPackage.TestWithGlobals'])
import Script2
print TestWithGlobals.__name__
print "TestWithGlobals:", TestWithGlobals.global_string
Script2.MakeStringBall()
print "TestWithGlobals:", TestWithGlobals.global_string
print "Script2.TestWithGlobals:", Script2.TestWithGlobals.global_string
Script2.py
from SubPackage import TestWithGlobals
print TestWithGlobals.__name__
import sys
def MakeStringBall():
print "In MakeStringBall", id(TestWithGlobals)
print "In MakeStringBall Subpackage.TestWithGlobals", id(sys.modules['SubPackage.TestWithGlobals'])
print "In MakeStringBall OuterPackage.SubPackage.TestWithGlobals", id(sys.modules['OuterPackage.SubPackage.TestWithGlobals'])
TestWithGlobals.global_string = "ball"
这个输出是:
In Script1 4301912560
SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
TestWithGlobals: test
In MakeStringBall 4301912784
In MakeStringBall Subpackage.TestWithGlobals 4301912784
In MakeStringBall OuterPackage.SubPackage.TestWithGlobals 4301912560
TestWithGlobals: test
Script2.TestWithGlobals: ball
python 中的导入系统构建新模块并通过它们在 sys.modules
缓存中的导入路径引用它们。在这种情况下,模块在 2 个不同的路径下导入,因此创建了 2 个不同的模块对象(正如您从 id 函数的输出中看到的那样)。
从不同的路径导入相同的 Python 模块似乎会导致创建两个不同的模块引用。
例如以下三个Python脚本。 Script1和Script2位于OuterPackage中,TestWithGlobals位于SubPackage中。
+ Root
|_+ OuterPackage
| - Script1
| - Script2
|_+ SubPackage
| - TestWithGlobals
脚本 1:
from OuterPackage.SubPackage import TestWithGlobals
import Script2
print TestWithGlobals.__name__
print TestWithGlobals.global_string
Script2.MakeStringBall()
print TestWithGlobals.global_string
和脚本 2:
from SubPackage import TestWithGlobals
print TestWithGlobals.__name__
def MakeStringBall():
TestWithGlobals.global_string = "ball"
最后是 TestWithGlobals 本身
global_string = "test"
现在,当 Script1 为 运行 时,输出如下:
SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
test
test
在 Script2 中将 from SubPackage
更改为 from OuterPackage.SubPackage
将导致 Script1 的不同输出:
OuterPackage.SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
test
ball
在 运行ning Script1.
之前将根目录附加到 pythonpath为什么引用同一个模块时,Script1 和 Script2 的 TestWithGlobals 不同?这背后的原因是什么?
如果您按如下方式更改代码,它会告诉您更多发生的事情:
Script1.py
import sys
from OuterPackage.SubPackage import TestWithGlobals
print "In Script1", id(sys.modules['OuterPackage.SubPackage.TestWithGlobals'])
import Script2
print TestWithGlobals.__name__
print "TestWithGlobals:", TestWithGlobals.global_string
Script2.MakeStringBall()
print "TestWithGlobals:", TestWithGlobals.global_string
print "Script2.TestWithGlobals:", Script2.TestWithGlobals.global_string
Script2.py
from SubPackage import TestWithGlobals
print TestWithGlobals.__name__
import sys
def MakeStringBall():
print "In MakeStringBall", id(TestWithGlobals)
print "In MakeStringBall Subpackage.TestWithGlobals", id(sys.modules['SubPackage.TestWithGlobals'])
print "In MakeStringBall OuterPackage.SubPackage.TestWithGlobals", id(sys.modules['OuterPackage.SubPackage.TestWithGlobals'])
TestWithGlobals.global_string = "ball"
这个输出是:
In Script1 4301912560
SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
TestWithGlobals: test
In MakeStringBall 4301912784
In MakeStringBall Subpackage.TestWithGlobals 4301912784
In MakeStringBall OuterPackage.SubPackage.TestWithGlobals 4301912560
TestWithGlobals: test
Script2.TestWithGlobals: ball
python 中的导入系统构建新模块并通过它们在 sys.modules
缓存中的导入路径引用它们。在这种情况下,模块在 2 个不同的路径下导入,因此创建了 2 个不同的模块对象(正如您从 id 函数的输出中看到的那样)。