修改
实施例,
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__
答案 0 :(得分:1)
删除我之前的答案,因为您显然需要多态,而不是多种返回类型。
所以,在Spyne中有两种做多态的方法:Python方式和Spyne方式。
让:
class A(ComplexModel):
i = Integer
class B(A):
s = Unicode
class C(A):
d = DateTime
Python方法使用duck typing来返回值。
让我们定义一个泛型类:
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。
答案 1 :(得分: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类型。