关于imp,我开始把他当做了一个简单的import来看
然后我运行下面这段代码,发现了一些奇怪的问题
a.py
A = {"position": "in a"}
class Test1(object):
@classmethod
def printA(cls):
print "I am in a.py"
print A
b.py
A = {"position": "in b"}
class Test2(object):
@classmethod
def printA(cls):
print "I am in b.py"
print A
3.py
import imp
a = imp.load_source("mod", "a.py")
b = imp.load_source("mod", "b.py")
obj1 = a.Test1()
obj2 = b.Test2()
obj1.printA()
obj2.printA()
结果
# python 3.py
I am in a.py
{'position': 'in b'}
I am in b.py
{'position': 'in b'}
我发现模块a.py中的常量A被b.py中的A给覆盖了。。。这个的主要原因是因为没有理解imp.load_source的用法。
官网上是这么写的
imp.
load_source
(name, pathname[, file])Load and initialize a module implemented as a Python source file and return its module object. If the module was already initialized, it will be initialized again. The name argument is used to create or access a module object. The pathname argument points to the source file. The file argument is the source file, open for reading as text, from the beginning. It must currently be a real file object, not a user-defined class emulating a file. Note that if a properly matching byte-compiled file (with suffix
.pyc
or.pyo
) exists, it will be used instead of parsing the given source file.
大概意思就是加载并初始化一个python源文件并且返回模块对象,如果模块已经被初始化,那么调用这个函数的话模块将再次被初始化。说起来有点绕,我们看个例子。
a.py
word = "In a"
class Test1(object):
@classmethod
def printA(cls):
print "I am in a.py"
b.py
class Test2(object):
@classmethod
def printA(cls):
print "I am in b.py"
3.py
import imp
a = imp.load_source("mod", "a.py")
b = imp.load_source("mod", "b.py")
print b.word
print dir(b)
运行python 3.py结果
# python 3.py
In a
['Test1', 'Test2', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'word']
可以看出,b中已经添加了a.py中的word这个属性
其实运行流程是这样的,将a.py载入到名字为mod的模块中,然后再将b.py载入到名为mod的模块中,相当于将两个模块a.py与b.py合并到名字为mod的模块里面
可以按下面这种方式验证
3.py
import imp
import sys
a = imp.load_source("mod1", "a.py")
b = imp.load_source("mod1", "b.py")
print sys.modules
结果,sys.modules里面已经有mod1了
root@qianyuqiao-All-Series:/home/codes# python 3.py | grep mod1
........,'mod1': , ....