【问题标题】:how do I inherit class with decorators in spyne如何在 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')

【问题讨论】:

    标签: python inheritance python-decorators spyne


    【解决方案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 测试。而且...这不是一个好的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-17
        • 2011-03-23
        • 2019-10-02
        • 2011-11-20
        • 2014-03-07
        • 2011-09-18
        • 2015-06-18
        • 2023-04-09
        相关资源
        最近更新 更多