如何在Python中打破导入循环

30

我有这样一种情况:有两个相关的大型Python类,因此我将它们放在不同的文件中。假设这些类是Cobra和Rat。

现在需要从Cobra的方法中调用Rat的方法,反之亦然。 为此,我需要在Rat.py中导入Cobra,在Cobra.py中导入Rat。

这会创建一个导入循环并产生错误。无法在Cobra内部导入Cobra。

如何解决?

Cobra.py

import Rat
class Cobra():
    def check_prey(self, rat ):
        # Some logic 
        rat.foo()

Rat.py:

import Cobra
class Rat():
    def check_predator(self, snake ):
        # some_logic ..
        snake.foo()

3
你展示的代码中没有呈现出那个问题。 - Ignacio Vazquez-Abrams
1
这不应该发生,两个类不能互相知道。如果您正在使用 RatCobra 类,那么考虑一个共同的基类 Animal 如何?这样您就可以在 RatCobra 中都导入 Animal - user2032433
10
“两个类无法彼此了解”这种说法是完全错误的。双向导航是面向对象编程的基本特征,也是大多数面向对象语言(如C++,Java,C#)中可用的功能之一。 - Martin Spamer
1
但是为什么眼镜蛇需要老鼠呢? - Markus Meskanen
1
@MarkusMeskanen ... 要吃它吗? :) - Jean-Francois T.
1个回答

43

如果在Rat类的定义中没有使用 Cobra 或反之亦然(即仅在方法内部使用),那么你实际上可以将导入语句移至文件底部,在此时类定义已经存在。

# Cobra.py
class Cobra:
    # ...
    def check_prey(self, rat):
        # some logic
        rat.foo()
    
import Rat
# Rat.py
import Cobra
class Rat:
    # ...
    def check_predator(self, snake):
       # some_logic ..
       snake.foo()

或者您可以限制导入的范围:

# Cobra.py
class Cobra:
    # ...
    def check_prey(self, rat):
        import Rat
        # some logic
        rat.foo()
# Rat.py
import Cobra
class Rat:
    # ...
    def check_predator(self, snake):
       # some_logic ..
       snake.foo()

如果您不直接使用RatCobra类名,则根本不需要导入语句:只要属性和函数存在于ratsnake实例中,Python就不关心它们来自哪个类。

通常,避免import循环没有绝对可靠的方法。最好的方法是重构您的代码并执行上述某些操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接