我该如何处理Google App Engine中的循环导入?

9 投票
4 回答
587 浏览
提问于 2025-04-15 17:04

如果我有一个文件叫 "a.py"

from google.appengine.ext import db
class A(db.Model):
    db.ReferenceProperty(b.B)
    ...other stuff

还有另一个文件叫 "b.py"

from google.appengine.ext import db
class B(db.Model):
    db.ReferenceProperty(a.A)
    ...other stuff

看起来 Python 不允许循环依赖。通常,我想你会修改代码,让这两个类能够在不直接互相导入的情况下解决彼此的问题。也许可以通过一个第三方的中介来整合它们之间的引用?但是我不能仅仅使用一个普通的中介类,因为所有的类最终都需要保存到数据库里?有没有什么正确的方法来结构化上面的代码,使其能够正常工作?

我感觉我会收到很多关于“代码味道”、“解耦”、“设计不良”等等的评论。所以我请求,如果你说这些,请举个实际的例子来说明你会怎么做。有没有什么解决方案可以让引用、类和模块保持原样?

谢谢。

4 个回答

1

如果你在同一个模块里定义了两个模型,会发生什么呢?比如说在一个叫 a_b.py 的文件里。

1

根据文档的说明:

ReferenceProperty还有一个很方便的功能:反向引用。当一个模型有一个指向另一个模型的ReferenceProperty时,每个被引用的实体都会得到一个属性,这个属性的值是一个查询,能够返回所有引用它的第一个模型的实体。

所以你应该可以使用这个自动添加的反向引用。

7

解决这个问题的方法是,在至少一个模型中使用一个引用属性,这个属性不限制特定的类,然后在你自己的代码中只允许引用那个特定的类。

比如,

class A(db.Model):
  b = db.ReferenceProperty()

class B(db.Model):
  a = db.ReferenceProperty(A)

你可以把任何模型的实例赋值给变量b;只要确保你只赋值真正的B类实例就可以了。

撰写回答