从子包导入或完整路径差异

蒂姆·德·哈斯

从不同的路径导入相同的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

和Script2:

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 SubPackagefrom OuterPackage.SubPackage会导致Script1的输出不同:

OuterPackage.SubPackage.TestWithGlobals
OuterPackage.SubPackage.TestWithGlobals
test
ball

在运行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函数的输出所示)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章