如果从其他路径导入,则模块将重新导入

发布于 2021-01-29 15:57:59

在我正在工作的大型应用程序中,几个人以不同的方式导入相同的模块,例如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代码和其他地方看到了与此相关的一些错误。

关注者
0
被浏览
185
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    如果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文件。在那种情况下,解决方案就是不要这样做。:-)



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看