0

编辑

例子,

class A(ComplexModel):
    Id = Unicode

class B(ComplexModel):
    __extends__ = A
    Name = Unicode

@rpc(String, _returns=A)
def hello(self, name):
    ret = B()
    B.Id = '123'
    B.Name = name
    return ret

您如何处理这种行为,使其不返回 的对象A


我将如何编写spyne装饰器以正确返回一种以上的类型?例如,如果 _returns 设置为,ZObj则返回一个XAccount(如代码中所示)不会执行任何操作。

我可以编写XAccount对象以使其扩展ZObj并且是有效的返回类型吗?

@rpc(String, _returns=(ZObj, XAccount))
def hello(self, name):
    acc = XAccount(
        user_name = name.upper(),
        first_name = name,
        last_name = 'last ' + name
    )
    return acc

类示例....

class ZObj(ComplexModel):
    id = Unicode(pattern='[a-zA-Z0-9]{32}|\d+')

class Account(DeclarativeBase):
    __tablename__ = 'account'

    id = Column(Integer, primary_key=True)
    user_name = Column(String(256))
    first_name = Column(String(256))
    last_name = Column(String(256))


class XAccount(TableModel):
    __table__ = Account.__table__
4

2 回答 2

1

删除我之前的答案,因为您显然需要多态性,而不是多个返回类型。

因此,在 Spyne 中进行多态性有两种方式:Python 方式和 Spyne 方式。

让:

class A(ComplexModel):
    i = Integer

class B(A):
    s = Unicode

class C(A):
    d = DateTime

Python 方式使用鸭子类型来返回值。

让我们定义一个泛型类:

class GenericA(ComplexModel):
    i = Integer
    s = Unicode
    d = DateTime

并将其用作我们示例服务的返回值:

class SomeService(ServiceBase):
    @rpc(Unicode(values=['A', 'B', 'C']), _returns=GenericA)
    def get_some_a(self, type_name):
        # (...)

这样,您可以获得数据,但它被标记为GenericA对象。如果您不关心这一点,您可以创建一个包含所有对象的所有类型的类(假设具有相同名称的属性具有相同的类型)并完成它。这很容易,稳定并且在今天有效。

如果这还不足以满足您的需求,您必须使用 Spyne 方式进行多态性。为此,首先将您的返回类型设置为基类:

class SomeService(ServiceBase):
    @rpc(Unicode(values=['A', 'B', 'C']), _returns=A)
    def get_some_a(self, type_name):
        # (...)

并将您的输出协议标记为多态:

application = Application([SomeService], 'tns',
    in_protocol=Soap11(validator='lxml'),
    out_protocol=Soap11(polymorphic=True)
)

这至少需要 Spyne-2.12。

工作示例:https ://github.com/arskom/spyne/blob/a1b3593f3754a9c8a6787c29ff50f591db89fd49/examples/xml/polymorphism.py

于 2015-07-14T06:57:30.400 回答
0

此外,您不需要这样做:

class Account(DeclarativeBase):
    __tablename__ = 'account'

    id = Column(Integer, primary_key=True)
    user_name = Column(String(256))
    first_name = Column(String(256))
    last_name = Column(String(256))

class XAccount(TableModel):
    __table__ = Account.__table__

这同样有效:

from spyne import TTableModel

TableModel = TTableModel() # Think of this as Spyne's declarative_base

class Account(TableModel):
    __tablename__ = 'account'

    id = Integer(primary_key=True)
    user_name = Unicode(256)
    first_name = Unicode(256)
    last_name = Unicode(256)

您的表元数据所在的位置TableModel.Attributes.sqla_metadata

以这种方式创建的对象可用于 SQLAlchemy 查询和 Spyne 类型。

于 2015-07-16T11:01:16.107 回答