您可以自己找出答案:
t1.py
#!/usr/bin/python
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug('t1 has started')
logger.debug('t2 is being imported')
import t2
logger.debug('A is being "compiled"')
class A:
flag = False
logger.debug('ID A: %r', id(A))
logger.debug('ID A.flag %r', id(A.flag))
logger.debug('What is __name__? %r', __name__)
if __name__ == "__main__":
logger.debug('__name__ was "__main__"')
logger.debug('Calling t2.f()')
t2.f()
logger.debug('t2.f() was called')
logger.debug('ID A.flag: %r', id(A.flag))
print(A.flag)
t2.py
#!/usr/bin/python
import logging
logger = logging.getLogger(__name__)
logger.debug('t2 is being imported')
logger.debug('t2 is now importing t1')
import t1
def f():
logger.debug('f is being called')
t1.A.flag = True
logger.debug('ID t1: %r', id(t1))
logger.debug('ID t1.A: %r', id(t1.A))
logger.debug('ID t1.A.flag: %r', id(t1.A.flag))
print(t1.A.flag)
我的输出
我要和 cmets 分开了
DEBUG:__main__:t1 has started
DEBUG:__main__:t2 is being imported
DEBUG:t2:t2 is being imported
DEBUG:t2:t2 is now importing t1
如您所见,第一次(正如其他人提到的)t1 实际上的名称为__main__。它尝试导入t2,但立即t2 尝试导入t1。
DEBUG:t1:t1 has started
DEBUG:t1:t2 is being imported
您可以看到没有任何t2 日志记录语句运行。那是因为 Python 缓存了导入的模块,所以它首先在缓存中查找 t2 并说:“啊哈!我已经导入了这个人,我只需要返回它。那么,给你!”
DEBUG:t1:A is being "compiled"
DEBUG:t1:ID A: 140377934341704
DEBUG:t1:ID A.flag 4312040768
DEBUG:t1:What is __name__? 't1'
所以,您会注意到现在它已经通过导入t1 实现了。还有t2
DEBUG:t2:t2 is done being imported
在__main__ t1 中继续执行
DEBUG:__main__:A is being "compiled"
DEBUG:__main__:ID A: 140377934344360
DEBUG:__main__:ID A.flag 4312040768
请注意,A 和 A.flag 的 id 是不同的!
DEBUG:__main__:What is __name__? '__main__'
DEBUG:__main__:__name__ was "__main__"
DEBUG:__main__:Calling t2.f()
DEBUG:t2:f is being called
DEBUG:t2:ID t1: 4317998840
DEBUG:t2:ID t1.A: 140377934341704
DEBUG:t2:ID t1.A.flag: 4312040736
再次注意,这些 ids 匹配 t1.As,而不是 __main__.As。
True
DEBUG:__main__:t2.f() was called
DEBUG:__main__:ID A.flag: 4312040768
False