你如何@rpc _returns spyne 中的多态类型?
How do you @rpc _returns polymorphic types in spyne?
编辑
示例,
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
您如何处理这种行为,使其 return 不是 A
的对象?
我如何将 spyne
装饰器正确地写成 return 不止一种类型?例如,如果 _returns 设置为 ZObj
,那么 returning 一个 XAccount
(就像在代码中一样)不会做任何事情。
我可以编写 XAccount
对象,使其扩展 ZObj
并且是有效的 return 类型吗?
@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 例子....
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__
删除我之前的回答,因为您显然需要多态性,而不是多种 return 类型。
因此,在 Spyne 中有两种实现多态性的方法:Python 方法和 Spyne 方法。
设:
class A(ComplexModel):
i = Integer
class B(A):
s = Unicode
class C(A):
d = DateTime
Python 方法使用鸭子输入 return 值。
让我们定义一个泛型 class:
class GenericA(ComplexModel):
i = Integer
s = Unicode
d = DateTime
并将其用作示例服务的 return 值:
class SomeService(ServiceBase):
@rpc(Unicode(values=['A', 'B', 'C']), _returns=GenericA)
def get_some_a(self, type_name):
# (...)
通过这种方式,您可以获得数据,但它被标记为 GenericA
对象。如果您不关心这个,您可以创建一个 class ,它具有所有对象的所有类型(假设具有相同名称的属性具有相同的类型)并完成它。这很简单,稳定并且今天可以使用。
如果这还不能满足您的需要,您必须按照 Spyne 的方式进行多态性处理。为此,首先将 return 类型设置为基础 class:
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。
此外,您不需要这样做:
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)
您的 table 元数据在 TableModel.Attributes.sqla_metadata
中的位置
以这种方式创建的对象可用于 SQLAlchemy 查询和 Spyne 类型。
编辑
示例,
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
您如何处理这种行为,使其 return 不是 A
的对象?
我如何将 spyne
装饰器正确地写成 return 不止一种类型?例如,如果 _returns 设置为 ZObj
,那么 returning 一个 XAccount
(就像在代码中一样)不会做任何事情。
我可以编写 XAccount
对象,使其扩展 ZObj
并且是有效的 return 类型吗?
@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 例子....
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__
删除我之前的回答,因为您显然需要多态性,而不是多种 return 类型。
因此,在 Spyne 中有两种实现多态性的方法:Python 方法和 Spyne 方法。
设:
class A(ComplexModel):
i = Integer
class B(A):
s = Unicode
class C(A):
d = DateTime
Python 方法使用鸭子输入 return 值。
让我们定义一个泛型 class:
class GenericA(ComplexModel):
i = Integer
s = Unicode
d = DateTime
并将其用作示例服务的 return 值:
class SomeService(ServiceBase):
@rpc(Unicode(values=['A', 'B', 'C']), _returns=GenericA)
def get_some_a(self, type_name):
# (...)
通过这种方式,您可以获得数据,但它被标记为 GenericA
对象。如果您不关心这个,您可以创建一个 class ,它具有所有对象的所有类型(假设具有相同名称的属性具有相同的类型)并完成它。这很简单,稳定并且今天可以使用。
如果这还不能满足您的需要,您必须按照 Spyne 的方式进行多态性处理。为此,首先将 return 类型设置为基础 class:
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。
此外,您不需要这样做:
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)
您的 table 元数据在 TableModel.Attributes.sqla_metadata
以这种方式创建的对象可用于 SQLAlchemy 查询和 Spyne 类型。