2

我的团队正在使用 Django 进行大型项目。为了简单起见,这里用普通的 Python 来说明问题(原始问题有模型和应用程序而不是类(我知道它们都是类)和包(我知道它们也是包))。

一个.py

from b import B1


class A1(object):
    def __init__(self):
        print "object A1"


class A2(object):
    def __init__(self):
        print "object A2"


A1()
B1()

b.py

from a import A2


class B1(object):
    def __init__(self):
        print "object B1"


A2()

a.py被调用时,它会尝试从b包中导入B1,另一方面,它会尝试从包中导入A2 然后从头开始,这将永远重复。蟒蛇说:

[dagrevis@localhost recursion]$ python2 a.py
Traceback (most recent call last):
  File "a.py", line 1, in <module>
    from b import B1
  File "/home/dagrevis/Python/recursion/b.py", line 1, in <module>
    from a import A2
  File "/home/dagrevis/Python/recursion/a.py", line 1, in <module>
    from b import B1
ImportError: cannot import name B1

解决方案之一是每个对象有一个文件。像 C++ 或 Java 这样的东西。然后我想起了 Guido 关于 Python 的话:“不要用 Python 编写 Java(或 C++,或 Javascript,...)。”。是否有更多 Pythonic 方式来处理这个问题?

感谢任何建议!

4

2 回答 2

4

您的用例不是“可解决的”。您可以将ImportError转换为AttributeError导入模块a(和b)而不是导入对象,但这不会改变您将无法使用这些模块的事实。

问题是您的模块a需要b在导入之前完全执行,但也需要在b导入a之前完全执行。

这根本无法解决,这是需要重构的明显症状:您的ab模块应该是单个模块(或者您可能想要进行更深入的重构)。

编辑:实际上你可以解决这个问题,即使我认为这样做很丑陋,在需要时将导入放在文件的末尾。但我认为这只是解决一些更大问题的补丁。

于 2012-09-18T10:37:00.643 回答
2

您的示例过于简化 - 它没有解释为什么需要周期性导入。但无论如何,这是将其重构为可运行代码的一种方法:

一个.py:

class A1(object):
    def __init__(self):
        print "object A1"


class A2(object):
    def __init__(self):
        print "object A2"

b.py:

class B1(object):
    def __init__(self):
        print "object B1"

c.py:

from a import A1, A2
from b import B1

A1()
A2()
B1()
于 2012-09-18T10:43:43.493 回答