python模块变量如何工作? [英] how do python module variables work?
问题描述
我曾经认为,一旦加载了模块,如果其他文件导入了相同的模块,或者以不同的方式导入模块,则不会重新导入。例如,我有 mdir / __ init __。py
,这是空的,而 mdir / mymod.py
,这是:
I used to think that once a module was loaded, no re-importing would be done if other files imported that same module, or if it were imported in different ways. For example, I have mdir/__init__.py
, which is empty, and mdir/mymod.py
, which is:
thenum = None
def setNum(n):
global thenum
if thenum is not None:
raise ValueError("Num already set")
thenum = n
def getNum():
if thenum is None:
raise ValueError("Num hasn't been set")
return thenum
前几个使用来自同一文件的案例按预期进行。此文件是 ./ usage.py
,同一文件夹 mdir
位于:
First few use cases from the same file go according to expectation. This file is ./usage.py
, the same folder mdir
is in:
import mdir.mymod
mdir.mymod.setNum(4)
print mdir.mymod.getNum()
from mdir import mymod
print mymod.getNum()
from mdir.mymod import *
print getNum()
try:
setNum(10)
except ValueError:
print "YHep, exception"
输出符合预期:
4
4
4
YHep, exception
但是,如果我弄乱系统路径,那么看起来模块会重新导入:
However, if I muck with the system path, then it looks like the module is imported anew:
#BEHOLD
import sys
sys.path.append("mdir")
import mymod
try:
mymod.getNum()
except ValueError:
print "Should not have gotten exception"
mymod.setNum(10)
print mymod.getNum()
print mdir.mymod.getNum()
那个代码,运行在之前的代码,收益率:
That code, running after the previous code, yields:
Should not have gotten exception
10
4
给出了什么?
推荐答案
mymod
和 mdir.mymod
被认为是不同的模块 - 这里有点相关的讨论: http://code.djangoproject.com/ticket/3951
mymod
and mdir.mymod
are considered different modules - here's somewhat related discussion: http://code.djangoproject.com/ticket/3951
说明:
最好使用python交互式解释器并自己查看。我在某个目录下创建了目录(包) mydir
,里面有两个文件(模块) - __ init __。py
和 mymod.py
,都是空的。我在包含 mydir
的目录中启动了python。现在看看会发生什么:
It's best to play with python interactive interpreter and see for yourself. I created directory (package) mydir
under some directory and inside it two files (modules) - __init__.py
and mymod.py
, both empty. I started python inside of directory containing mydir
. Now see what happens:
>>> import mydir.mymod
>>> from mydir import mymod
>>> mymod == mydir.mymod
True
为什么 mymod
和 mydir.mymod
考虑过同样的事情?好吧,两个名称都引用相同的模块对象 - 模块相等性由它们的路径比较确定:
Why are mymod
and mydir.mymod
considered the same thing? Well, both names refer to the same module object - modules equality is determined by their paths comparison:
>>> mymod
<module 'mydir.mymod' from 'mydir\mymod.py'>
>>> mydir.mymod
<module 'mydir.mymod' from 'mydir\mymod.py'>
现在,如果我改变 sys.path
包含 mydir
并导入 mymod
,以便导入模块的 path 与众不同:
Now, if I alter sys.path
to contain mydir
and import mymod
in such a way that path of imported module will seem to be different:
>>> import sys
>>> sys.path.append( "d:/zrodla/stack/mydir" )
# note that importing mymod (and not mydir.mymod) prior to appending mydir to
# path would cause an error
>>> mymod2
<module 'mymod' from 'd:/zrodla/stack/mydir\mymod.pyc'>
>>> mymod2 == mydir.mymod
False
然后生成的模块对象将不会比较相等。这样一个模块将被导入两次 - 这是正常的,这就是python的工作方式。请记住,导入的模块是由它们的路径标识的 - 更具体地说,我想是'虚线路径' - 看看 sys.modules
键:
then resulting module objects will not compare equal. This way one module will be imported twice - it's normal and that's the way python works. Just remember that imported modules are identified by their paths - more specifically by 'dotted paths' I think - look at sys.modules
keys:
>>> [x for x in sys.modules.keys() if "my" in x]
['mydir', 'mymod', 'mydir.mymod']
我希望现在很清楚。
这篇关于python模块变量如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!