2015-09-14 66 views
0

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

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) 
  • 我的代码的设计,强烈要求山雀和达在自己的模块。
  • 非常重要的是,tit或tat可能是第一个加载的模块。
  • 这是可能的python在任何方式?下面===

===原来的问题我有很多几十个常数等的base_module它是由许多进口, 而且进口什么。在这里面我有基础模块中的重点班,这取决于一个漂亮的打印机模块做事情的印刷:

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”功能(我假设,因为循环引用)

我的最终目标是迫使pprint的负荷。随时加载base_module,并且 允许pprint取决于base_module中的几十个常量。

这不可能吗?

+0

我不认为这与循环引用有关。您应该在基本模块中导入pprint,因为这是合同的地方。如果你在本地导入它,那么导入的对象范围只在该本地函数中,所以任何想使用'pprint.to_str()'的人都必须'导入pprint'。你必须记住python是动态解析的,所以'x = 0; def p():print(x); x = 1; p()'打印1不是0. – AChampion

+2

你能否给一个[mcve]更好地展示你想要达到的目标?这些常量在哪里定义了'pprint'要求,为什么不将它打包到一个实用程序函数/模块中供您的项目的其余部分使用? – jonrsharpe

+0

@achampion pprint必须导入base_module,因为它有几十个所需的常量等现在你告诉我动态地执行pprint的导入来打破循环。这听起来不错,如果你看看我上面的第二个代码块,你会看到我在对象打印过程中有一个动态的pprint导入。这工作99%的时间。有时候pprint模块将不具有to_str功能。我认为这发生在一个模块被循环加载时。例如在执行第一次加载期间,它会导入一个递归重新导入它的模块。我看不出如何避免! –

回答

1

不幸的是我不能重现你的问题。 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中很少发生的问题? 你能提供一个你遇到的问题的最小例子吗?

+0

在我的每一个模块中,我通常都会有一个'inst'变量,它将包含一个类(例如打印机)的单例,您经常只使用它。这些'inst'变量的代码在LOAD时执行。因此,如果它试图利用其他本身处于动态加载过程中的类的依赖关系,它可能会崩溃。我的目标是在其源代码所在的类中具有初始化对象,并自动创建它们。但也许这不会发生。 –

+0

我接受你的回答,这是正确的,但我从来没有设法表达我的实际问题。我的代码总是在解释器中运行,但在调试器窗口内打印值时,__repr __()方法未运行。但删除越来越多的初始化代码我最终得到它的工作....但我真的不知道内部调试器环境之间有什么不同。和主要的环境。谢谢 –