python模块变量如何工作? [英] how do python module variables work?

查看:119
本文介绍了python模块变量如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经认为,一旦加载了模块,如果其他文件导入了相同的模块,或者以不同的方式导入模块,则不会重新导入。例如,我有 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆