Circular (or cyclic) imports in Python

前端 未结 12 2644
醉梦人生
醉梦人生 2020-11-21 05:23

What will happen if two modules import each other?

To generalize the problem, what about the cyclic imports in Python?

12条回答
  •  礼貌的吻别
    2020-11-21 05:40

    Circular imports can be confusing because import does two things:

    1. it executes imported module code
    2. adds imported module to importing module global symbol table

    The former is done only once, while the latter at each import statement. Circular import creates situation when importing module uses imported one with partially executed code. In consequence it will not see objects created after import statement. Below code sample demonstrates it.

    Circular imports are not the ultimate evil to be avoided at all cost. In some frameworks like Flask they are quite natural and tweaking your code to eliminate them does not make the code better.

    main.py

    print 'import b'
    import b
    print 'a in globals() {}'.format('a' in globals())
    print 'import a'
    import a
    print 'a in globals() {}'.format('a' in globals())
    if __name__ == '__main__':
        print 'imports done'
        print 'b has y {}, a is b.a {}'.format(hasattr(b, 'y'), a is b.a)
    

    b.by

    print "b in, __name__ = {}".format(__name__)
    x = 3
    print 'b imports a'
    import a
    y = 5
    print "b out"
    

    a.py

    print 'a in, __name__ = {}'.format(__name__)
    print 'a imports b'
    import b
    print 'b has x {}'.format(hasattr(b, 'x'))
    print 'b has y {}'.format(hasattr(b, 'y'))
    print "a out"
    

    python main.py output with comments

    import b
    b in, __name__ = b    # b code execution started
    b imports a
    a in, __name__ = a    # a code execution started
    a imports b           # b code execution is already in progress
    b has x True
    b has y False         # b defines y after a import,
    a out
    b out
    a in globals() False  # import only adds a to main global symbol table 
    import a
    a in globals() True
    imports done
    b has y True, a is b.a True # all b objects are available
    

提交回复
热议问题