我在许多Spyne示例中看到,所有方法都没有典型的self
参数;没有使用self
参数的Spyne示例,也没有使用cls
。它们使用ctx
参数,但ctx
不引用实例也不引用类(我需要维护某些状态)。
可以使用它吗?或者是没有实例化的类,并用作静态类?
我试图做类似的事情:
# -*- coding: utf-8 -*-
from __future__ import (
absolute_import,
unicode_literals,
print_function,
division
)
from spyne.decorator import rpc
from spyne.service import ServiceBase
from spyne.model.primitive import String
class RadianteRPC(ServiceBase):
def __init__(self, name):
self._name = name
@rpc(_returns=String)
def whoami(self):
"""
Dummy test method.
"""
return "Hello I am " + self._name + "!"
这段代码的问题是,RadianteRPC
似乎永远不会被Spyne实例化为对象,而是用作静态类。
解决方案1: 就目前而言,Spyne不会实例化任何对象。然后,如果我们需要存储一些状态,我们可以通过类属性来完成。
由于我们无法访问方法中的cls
参数,因此我们需要通过名称来引用类,因此我们可以执行以下操作:
class RadianteRPC(ServiceBase):
_name = "Example"
@rpc(_returns=String)
def whoami(ctx): # ctx is the 'context' parameter used by Spyne
"""
Dummy test method.
"""
return "Hello I am " + RadianteRPC._name + "!"
解决方案2(在Spyne邮件列表中找到):
在许多情况下,我们可能无法直接引用类名,因此我们有另一种选择:通过ctx参数查找类。
class RadianteRPC(ServiceBase):
_name = "Example"
@rpc(_returns=String)
def whoami(ctx): # ctx is the 'context' parameter used by Spyne
"""
Dummy test method.
"""
return "Hello I am " + ctx.descriptor.service_class._name + "!"
答案 0 :(得分:1)
我所做的是继承Application类,然后通过ctx.app访问应用程序对象。
from spyne.protocol.soap.soap11 import Soap11
from spyne.server.wsgi import WsgiApplication
from spyne import Application, rpc, ServiceBase, Unicode, Boolean
class MyApplication(Application):
def __init__(self, *args, **kargs):
Application.__init__(self, *args, **kargs)
assert not hasattr(self, 'session')
self.session = 1
def increment_session(self):
self.session += 1
def get_session(self):
return self.session
class Service(ServiceBase):
@rpc(_returns=Integer)
def increment_session(ctx):
s = ctx.app.get_session()
self.increment_session()
return s
application = MyApplication([MatlabAdapterService],
'spyne.soap',
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11())
wsgi_application = WsgiApplication(application)
...
我想应该有一种“更清洁”的方式 - 不需要继承Application类的子类 - 通过继承Context,但这应该允许你动态工作。
要回到您的问题,您还有机会访问您的服务,因为这是在Application.services属性中定义的。