2014-10-30 45 views
1

说我有一个模块看起来像这样:Python和循环进口再次

circlejerking/ 
├── bar.py 
├── foo.py 
└── __init__.py 

bar.py:

from .foo import Foo 

class Bar(Foo): 
    pass 

foo.py:

from .bar import Bar 

class Foo(object): 
    my_bar = Bar() 

__init__.py:

from .foo import Foo 
from .bar import Bar 

__all__ = [ 
    'Foo', 
    'Bar' 
] 

使用该模块因循环导入而失败。

In [1]: from circlejerking import Foo 
--------------------------------------------------------------------------- 
ImportError Traceback (most recent call last) 
<ipython-input-1-2258014c7099> in <module>() 
----> 1 from circlejerking import Foo 

/home/me/circlejerking/__init__.py in <module>() 
----> 1 from .foo import Foo 
2 from .bar import Bar 
3 
4 __all__ = [ 
5 'Foo', 

/home/me/circlejerking/foo.py in <module>() 
----> 1 from .bar import Bar 
2 
3 class Foo(object): 
4 my_bar = Bar() 

/home/me/circlejerking/bar.py in <module>() 
----> 1 from .foo import Foo 
2 
3 class Bar(Foo): 
4 pass 

ImportError: cannot import name Foo 

我明白的问题,我知道,那蟒蛇相关的圆形进口问题已讨论多次,但我似乎无法得到这个工作。 两个转到答案SO有针对此问题是:

  1. 重新设计你的代码,你持有它错或
  2. 导入其他模块只在你需要它。

我相当肯定,我的设计是好的,是的,我相信这两个班其实不是一回事。

在其他地方导入其他类不是一个选项,因为我需要它们在正确的位置。

任何想法?

+0

也许将所有导入移动到'__init__'?这样你的进口订单就一劳永逸地解决了 – inspectorG4dget 2014-10-30 18:08:54

+0

这应该是'Bar Bar(Foo)'类吗?现在你根本没有任何叫“酒吧”的东西。另外,你为什么“需要”这种方式? – BrenBarn 2014-10-30 18:09:21

+0

您的问题比循环进口更糟糕;你的类实际上有循环*引用*,即使它们都在同一个文件中定义,它也不能在Python中解析。看[这个问题](http://stackoverflow.com/questions/3270045/python-circular-references)。你确定你需要'my_bar'作为类属性而不是实例属性吗? – BrenBarn 2014-10-30 18:13:08

回答

0

一般来说,你可以用注射方式解决这个问题:

该模块是细如-是:

from .foo import Foo 
class Bar(Foo): 
    pass 

那么你其他的模块就成为:

class Foo(object): 
    bar = None 

    @classmethod 
    def set_bar(cls, bar): 
     cls.bar = bar 

这是再向上到任何使用Foo来确保set_bar在使用之前被适当地调用。