2010-01-08 109 views
21

在编写python模块时,有没有办法阻止它被客户端代码导入两次?就像c/C++头文件一样:如何防止两次导入模块?

#ifndef XXX 
#define XXX 
... 
#endif 

非常感谢!

回答

30

Python模块不会导入多次。只需运行两次导入不会重新加载模块。如果你想重新加载,你必须使用reload声明。这里有一个演示

foo.py与单线

print "I am being imported" 

模块,这里是多个进口尝试的屏幕成绩单。

>>> import foo 
    Hello, I am being imported 
    >>> import foo # Will not print the statement 
    >>> reload(foo) # Will print it again 
    Hello, I am being imported 
+7

请注意,'重载()'不会修复了旧模块的任何引用,所以实际上不是那么有用。 – 2010-01-08 17:56:07

+0

这是一个重要的观点。谢谢。 – 2010-01-08 18:01:01

+1

参考资料:http://docs.python.org/tutorial/modules.html#more-on-modules。 http://docs.python.org/reference/simple_stmts.html#the-import-statement – 2010-01-08 20:39:30

13

导入缓存,只能运行一次。其他导入只会花费sys.modules中的查找时间。

9

在其他的答案中指定,的Python遇到第二个import语句它时,一般不重新加载的模块。相反,它会从sys.modules返回其缓存版本,而不执行任何代码。

但是有几个陷阱值得注意:

  • 导入主模块作为一个普通的模块有效地创建不同的名字在同一模块的两个实例。

    这是因为程序启动期间the main module is set up with the name __main__。因此,将其作为普通模块导入时,Pythonsys.modules中未检测到它,并再次导入它,但第二次输入它的专有名称。

    考虑文件/tmp/a.py具有以下内容:

    # /tmp/a.py 
    import sys 
    
    print "%s executing as %s, recognized as %s in sys.modules" % (__file__, __name__, sys.modules[__name__]) 
    import b 
    

    另一个文件/tmp/b.pya.py一个import语句(import a )。
    执行/tmp/a.py结果如下输出:

    [email protected]:/tmp$ python a.py 
    a.py executing as __main__, recognized as <module '__main__' from 'a.py'> in sys.modules 
    /tmp/a.pyc executing as a, recognized as <module 'a' from '/tmp/a.pyc'> in sys.modules 
    

    因此,最好是保持主模块相当小,且大部分的功能输出到外部模块,如建议here

  • This answer指定两个可能的方案:

    1. 稍有不同的import语句使用不同的条目sys.path导致同一模块。
    2. 尝试在前一个模块中途失败后再次导入模块。
+2

这实际上帮助我解决了这个问题,其他答案并不完整。 – Tapuzi 2016-06-26 16:13:02

+1

这就是我要找的。谢谢。 – bfrguci 2016-08-01 23:15:44