如果从其他路径导入,则模块将重新导入
在我正在工作的大型应用程序中,几个人以不同的方式导入相同的模块,例如import x或从y import
x,其副作用是x被两次导入,并且如果有人依靠全局属性,可能会引入非常细小的错误。
例如,假设我有一个mypakcage软件包,其中包含三个文件mymodule.py,main.py和 init .py
mymodule.py内容
l = []
class A(object): pass
main.py内容
def add(x):
from mypackage import mymodule
mymodule.l.append(x)
print "updated list",mymodule.l
def get():
import mymodule
return mymodule.l
add(1)
print "lets check",get()
add(1)
print "lets check again",get()
它打印
updated list [1]
lets check []
updated list [1, 1]
lets check again []
因为现在在两个不同的模块中有两个列表,类似地,类A也不同。对我来说,它看起来很严重,因为类本身将被不同地对待,例如,下面的代码打印为False
def create():
from mypackage import mymodule
return mymodule.A()
def check(a):
import mymodule
return isinstance(a, mymodule.A)
print check(create())
题:
有什么办法可以避免这种情况?除了强制该模块应以一种方式导入onyl。这不能由python导入机制处理,我已经在Django代码和其他地方看到了与此相关的一些错误。
-
如果main.py是您实际运行的文件,则只能复制此文件。在这种情况下,您将在sys路径上获得main.py的当前目录。但是您显然还设置了系统路径,以便可以导入mypackage。
在那种情况下,Python不会意识到mymodule和mypackage.mymodule是同一模块,您将获得这种效果。此更改说明了这一点:
def add(x): from mypackage import mymodule print "mypackage.mymodule path", mymodule mymodule.l.append(x) print "updated list",mymodule.l def get(): import mymodule print "mymodule path", mymodule return mymodule.l add(1) print "lets check",get() add(1) print "lets check again",get() $ export PYTHONPATH=. $ python mypackage/main.py mypackage.mymodule path <module 'mypackage.mymodule' from '/tmp/mypackage/mymodule.pyc'> mymodule path <module 'mymodule' from '/tmp/mypackage/mymodule.pyc'>
但是在currect目录中添加另一个主文件:
realmain.py: from mypackage import main
结果是不同的:
mypackage.mymodule path <module 'mypackage.mymodule' from '/tmp/mypackage/mymodule.pyc'> mymodule path <module 'mypackage.mymodule' from '/tmp/mypackage/mymodule.pyc'>
因此,我怀疑您的软件包中包含主python文件。在那种情况下,解决方案就是不要这样做。:-)