可以缓存Python的suds客户端吗?

4 投票
3 回答
6030 浏览
提问于 2025-04-16 06:31

我现在正在用 Python 的 suds 库处理一个 wsdl 文件和它对应的 50 多个 xsd 文件。调用 Client 的过程大约需要 90 秒:

from suds.client import Client
url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
client = Client(url)

在我运行上面最后一行代码后,我得到了一个 Client 实例。创建这个客户端的过程花费了很长时间。请问缓存能否用于 Python 对象,还是仅限于像字符串和整数这样的基本数据类型?

我想在代码中实现的功能,虽然语法不对,但主要是想表达我的意图:

from suds.client import Client


if 'current_client' in cache:
    client = cache.get('current_client')
else:
    url = 'http://localhost:7080/webservices/WebServiceTestBean?wsdl'
    client = Client(url)
    cache.put('current_client', client)

3 个回答

0

suds 版本大于等于 0.3.5 r473 提供了一些网址缓存功能。默认情况下,像获取 WSDL 和导入 XSD 这样的 HTTP 请求会被缓存起来。

0

如果我理解你的问题没错的话,你是想避免每次都创建一个新的 Client(),而是想把它放到缓存里,这样就可以随时取出来。但我觉得你可能把事情搞复杂了,我建议你使用 单例模式。这样的话,你只需要创建一个客户端的实例,以后每次想要新实例时,它都会返回之前创建的那个实例。

这里有个例子,可以帮助你理解我所说的。

class MyClient(Client):

    __instance__ = None

    def __new__(cls, *args, **kws):
        if not cls.__instance__:
            cls.__instance__ = super(Client, cls).__new__(cls, *args, **kws)
        return cls.__instance__

另外,我本来想用 博格模式,这个模式和单例模式类似,但更好看。不过我没能找到方法来避免调用 Super.init(这个过程比较耗时),同时又能共享相同的状态。如果有人有更好的主意,如何用博格模式实现这一点,那就太好了。不过我觉得在这种情况下,博格模式可能不太适用。

希望这些能对你有帮助。

4

suds 默认会缓存 WSDL 和 XSD 文件一天,这样每次创建 Client 对象时就不需要再发请求去获取这些文件了。

90秒听起来真的很长,这段时间是用来等待 WSDL 的响应,还是在解析 WSDL 呢?如果解析 WSDL 需要这么久,那内置的缓存就没什么用处了。

我之前做过类似的事情,不过我没有用单例模式,而是用了一个模块级的全局字典。这其实就是单例模式,只是没有那么多 class 的复杂内容。

像这样:

from suds.client import Client

_clients = {}

def get_client(name):
    if name not in _clients:
        _clients[name] = Client(url_for_name)
    return _clients[name]

撰写回答