如果从不同路径导入,则重新导入模块
问题描述
在我工作的一个大型应用程序中,几个人以不同的方式导入相同的模块。 导入x 或 从y导入x 这样做的副作用是x被导入两次,如果有人依赖全局属性,可能会引入非常细微的错误例如,假设我有一个包mypakage,其中包含三个文件mymode.py、main.py和init.py
mymode.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类也是不同的
对我来说,它看起来足够严重,因为课程本身将受到不同的对待
例如,下面的代码打印错误
def create():
from mypackage import mymodule
return mymodule.A()
def check(a):
import mymodule
return isinstance(a, mymodule.A)
print check(create())
问题:
有什么方法可以避免这种情况吗?除了强制执行该模块外,应该单向导入该模块。这难道不能通过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文件在包中。在这种情况下,解决方案是不要这样做。:-)
相关文章