【问题标题】:How to use the 'self' param inside Spyne server methods如何在 Spyne 服务器方法中使用“自我”参数
【发布时间】:2014-08-14 10:42:54
【问题描述】:

我在许多 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 + "!"

【问题讨论】:

  • 您能举个例子吗?方法是用@staticmethod还是@classmethod装饰的?
  • 不,这些方法没有用 staticmethod 或 classmethod 修饰。该问题与 Spyne 架构有关,不是“Python”问题。
  • @jonrsharpe 我添加了对我的问题的更好解释。我需要重新打开问题以添加解决方案作为答案。
  • 就目前而言,这仍然不是一个好问题 - 例如,您之前的尝试究竟发生了什么?错误(提供完整的追溯)?考虑阅读this checklist
  • 提供回溯是没有意义的(回溯没有提供任何解决方案的线索)。是的,我进行了研究,深入研究了 Spyne 源代码,并且阅读了文档。

标签: python spyne


【解决方案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 属性中定义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多