如何在 spyne 中使用装饰器继承类
Posted
技术标签:
【中文标题】如何在 spyne 中使用装饰器继承类【英文标题】:how do I inherit class with decorators in spyne 【发布时间】:2013-09-26 21:20:29 【问题描述】:我正在尝试继承这样的装饰类
class SOAPCategoy(ComplexModel):
id = Integer
CategoyName = Unicode
class SOAPServiceBase(ServiceBase):
@rpc(Integer, _returns=SOAPSeller)
def Item(self, pId):
....
return SOAPCategory()
class SOAPCategoryService(SOAPServiceBase):
pass
.
.
.
wsgi_app = wsgi_soap_application([SOAPCategoryService], 'test.soap')
然后它抛出一个错误:
File "...spyne/interface/xml_schema/_base.py", line 186, in build_validation_schema
f = open('%s/%s.xsd' % (tmp_dir_name, pref_tns), 'r')
IOError: [Errno 2] No such file or directory: '/tmp/spyne9y_uw9/tns.xsd'
_base.py 部分源码
def build_validation_schema(self):
"""Build application schema specifically for xml validation purposes."""
self.build_schema_nodes(with_schema_location=True)
pref_tns = self.interface.get_namespace_prefix(self.interface.tns)
tmp_dir_name = tempfile.mkdtemp(prefix='spyne')
logger.debug("generating schema for targetNamespace=%r, prefix: "
"%r in dir %r" % (self.interface.tns, pref_tns, tmp_dir_name))
# serialize nodes to files
for k, v in self.schema_dict.items():
file_name = '%s/%s.xsd' % (tmp_dir_name, k)
f = open(file_name, 'wb')
etree.ElementTree(v).write(f, pretty_print=True)
f.close()
logger.debug("writing %r for ns %s" % (file_name,
self.interface.nsmap[k]))
f = open('%s/%s.xsd' % (tmp_dir_name, pref_tns), 'r')
【问题讨论】:
【参考方案1】:Spyne 旨在防止您对ServiceBase
子级使用继承。你必须使用组合。
class SOAPServiceBase(ServiceBase):
@rpc(Integer, _returns=SOAPSeller)
def Item(self, pId):
# ....
return SOAPCategory()
class SOAPCategoryService(ServiceBase):
# ...
wsgi_app = wsgi_soap_application([SOAPServiceBase, SOAPCategoryService], 'test.soap')
如果您需要从不同的端点导出相同的服务包,您应该这样做:
def TSoapServiceBase():
class SOAPServiceBase(ServiceBase):
@rpc(Integer, _returns=SOAPSeller)
def Item(self, pId):
# ....
return SOAPCategory()
return SOAPServiceBase
some_app = wsgi_soap_application([TSoapServiceBase()], 'test.soap')
some_other_app = wsgi_soap_application([TSoapServiceBase()], 'test.soap')
# etc...
【讨论】:
【参考方案2】:如果你想替换一些服务方法,你可以从父服务类扩展一个服务和下一个复制方法:
# Define main service class.
class OldService(ServiceBase):
@srpc(Unicode, _returns=Unicode)
def some_method(input):
return u'Original!'
# Overload service class.
class NewService(OldService):
@srpc(Unicode, Unicode, Unicode, _returns=Unicode)
def some_method(input1, input2, input3):
return u'Replaced!'
# Attach old methods.
for base in NewService.__bases__:
if issubclass(base, ServiceBase):
for name, method in base.public_methods.iteritems():
if name not in NewService.public_methods:
NewService.public_methods[name] = method
使用 Spyne 2.11.0 测试。而且...这不是一个好的解决方案。
【讨论】:
以上是关于如何在 spyne 中使用装饰器继承类的主要内容,如果未能解决你的问题,请参考以下文章