【问题标题】:Circular import in marshmallow棉花糖中的循环导入
【发布时间】:2016-01-25 20:55:57
【问题描述】:

我有两个相互关联的对象。我希望能够通过相关属性通过另一个对象访问一个对象。

例如A.b_relationship.obj.some_property

如何在不创建循环导入的情况下做到这一点?

# lib.py
class Relationship(object):

    def __init__(self, obj):
        self.obj = obj


# a.py
class A(object):
    b_relationship = Relationship(B)

# b.py
class B(object):
    a_relationship = Relationship(A)

为了清楚起见,我添加了这个附加示例。显然 SQLAlchemy 已经用backref 属性解决了这个问题。我不确定在不破坏其工作方式的情况下将这种东西实现到棉花糖中有多可行。也许我需要改变我的心态?

from marshmallow import Schema
from marshmallow.fields import String

from project.database import db


class PersonModel(db.Model):
    name = db.Column(db.String)


class PetModel(db.Model):
    name = db.Column(db.String)
    owner = db.relationship('PersonModel', backref='pets')


class PersonSchema(Schema):
    name = fields.String(init_arg='some value')
    pets = fields.Relationship(related_schema=PetSchema)


class PetSchema(Schema):
    name = fields.String()
    owner = fields.Relationship(related_schema=PersonSchema)

【问题讨论】:

  • 创建一个__init__ 并在那里导入AB。然后可以避免在 a.py 和 b.py 中循环导入。 This might be relevant
  • 您说您有两个相互关联的对象,但您是在类级别设置关系。虽然类确实是对象,但这似乎不是一个有用的创建链接。您是否希望将 A 的实例链接到 B 的实例,反之亦然,还是希望将类链接?类级链接非常无用。另外,这些类的实例是如何创建的?它们是一起存在的,还是独立创建的?
  • @user2357112 类本身不应链接在一起。他们不关心彼此。它需要链接的_relationship 属性。我稍后会关闭这些字段并使用链接的 obj 进行一些计算。
  • @user2357112 基本上,我希望能够通过A.rel 获得BB.rel 获得A
  • 呃...我在上面回复了您的回复,但现在您的最新评论更加混乱。您要关联classes 还是objects

标签: python python-import importerror marshmallow


【解决方案1】:

从这里: http://marshmallow.readthedocs.org/en/latest/nesting.html#two-way-nesting

查看字符串是如何用于类的; AuthorSchema 指的是“BookSchema”:

class AuthorSchema(Schema):
    # Make sure to use the 'only' or 'exclude' params
    # to avoid infinite recursion
    books = fields.Nested('BookSchema', many=True, exclude=('author', ))
    class Meta:
        fields = ('id', 'name', 'books')

class BookSchema(Schema):
    author = fields.Nested(AuthorSchema, only=('id', 'name'))
    class Meta:
        fields = ('id', 'title', 'author')

我假设在您的情况下,您想对 many=False 做同样的事情。我从来没有使用过棉花糖,但在 Django 中,它是相似的,我们使用类路径如“my_app.MyClass”而不是MyClass 来避免循环导入。

【讨论】:

  • 谢谢老兄!我没有意识到棉花糖已经有了这个功能。这就是我假设的结果。
【解决方案2】:

您可以实现RelationshipManager(也称为注册表),所有可以成为关系一部分的类都必须注册到该注册表中。

Relationship 初始化器可以采用与其相关的类的名称,而不是实际的类对象。

最后,关系类本身可以从初始化时给出的名称(通过管理器)延迟加载与其相关的真实类。

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2018-09-08
    • 1970-01-01
    • 2017-02-02
    • 1970-01-01
    • 2016-03-15
    相关资源
    最近更新 更多