在python导入中跳过子目录

时间:2014-06-02 21:15:30

标签: python import

好的,所以我想改变这个:

app/
    - lib.py
    - models.py
    - blah.py

进入这个:

app/
    - __init__.py
    - lib.py
    - models/
        - __init__.py
        - user.py
        - account.py
        - banana.py
    - blah.py

仍然可以使用from app.models import User导入我的模型,而不必在整个地方将其更改为from app.models.user import User。基本上,我希望所有内容都将程序包视为单个模块,但能够将代码导航到单独的文件中以便于开发。

我无法将for file in __all__: from file import *添加到 init .py中的原因是我在模型文件之间有循环引用。我不想要的修复是从使用它们的函数中导入这些模型。但这太丑了。让我举个例子:

user.py

...
from app.models import Banana
...

banana.py

...
from app.models import User
...

我编写了一个快速的预处理脚本,它抓取所有文件,重新编写它们以将导入放在顶部,并将其放入models.py中,但这几乎没有改进,因为现在我的堆栈跟踪没有显示我实际需要更改的行号。

有什么想法吗?我总是认为 init 可能是神奇的,但现在我深入研究它,我找不到任何能让我为自己提供这种简单方便的东西。

1 个答案:

答案 0 :(得分:1)

这取决于您的循环引用的用途。如果你有一个继承自Banana的用户类和一个继承自User的香蕉类,你就不能这样做。如果每个类定义了一个在另一个中使用的装饰器或者在实际导入期间调用的任何其他东西,你也不能这样做。

但是,如果您只是相互引用辅助函数,或者如果您的User对象具有创建Banana的新实例的方法,并且您的Banana对象具有创建User的新实例的方法,则可以。只要相互引用实际上没有被使用,直到模块中的某些内容从外部被调用,那么在模型文件夹中,在__init__.py中,您可以执行以下操作:

import user
import banana
#etc...
user.banana = banana
banana.user = user
#etc...

User = user.User
Banana = banana.Banana

然后为了清楚起见而不是试图弄清楚发生了什么