如果从不同路径导入,则重新导入模块

2022-03-31 00:00:00 python python-import

问题描述

在我工作的一个大型应用程序中,几个人以不同的方式导入相同的模块。 导入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文件在包中。在这种情况下,解决方案是不要这样做。:-)

相关文章