打破 Python 循环导入

Breaking Python Circular Imports

如何打破这个特定的循环导入。我在顶部添加了一个简单的示例来突出显示该问题。

module_tit.py

import tat
class Tit
    def tit(x):
        return tat.inst.tat(x)

inst = Tit()

if __name__=='__main__:
    print "tit 12 %s" % inst.tit(12)

module_tat.py

import tit
class Tat:
    def tat(x):
        if x>0:  return tit.inst.tit(x-1)
        else: return 'bottom'

inst = Tat()

if __name__=='__main__:
    print "tat 5 %s" % inst.tat(5)

=== 原问题如下 ===

我有一个 base_module 有许多常量等。它被许多人导入, 它什么都不进口。我在基本模块中有一个键 class,它依赖于一个漂亮的打印机模块来打印 Thing:

to_str = None
class Thing_Version1(object):
    def __repr__():
        to_str(self)

在漂亮的打印机模块中我有:

def to_str(x):
    ...
import base_module
base_module.to_str = to_str  

当漂亮的打印机模块设置 "base_module.to_str" 以便一切正常工作。这在 99% 的时间都有效,但在调试器中,它不够聪明,无法加载漂亮的打印机(即使在普通的解释器中,我的加载过程确实强制最终加载 pprint 模块。我考虑的另一种方法是动态导入:

class Thing_Version1(object):
    def __repr__():
        import pprint
        pprint.to_str(self)

但这也失败了。有时它在 pprint 模块中找不到 'to_str' 函数(我假设是因为循环引用)

我的最终目标是在任何时候 base_module 加载时强制加载 pprint,并且 允许 pprint 依赖于 base_module.

中的几十个常量

这不可能吗?

很遗憾,我无法重现您的问题。 Python 具有动态分辨率,因此循环引用很少成为问题:

fred.py

import wilma
count = 4
def main():
    wilma.pr('Hello')

wilma.py

import fred
def pr(str):
    print(str*fred.count)

Python REPL

>>> import fred
>>> fred.main()
HelloHelloHelloHello

您是否在努力避免 Python 中很少发生的问题? 你能提供一个最简单的例子来说明你遇到的问题吗?