我使用带有单例模式的python类来获得不同类型的好处,例如
但是现在也有一些问题,所以让我知道如何解决这个问题,但得到了上面提到的单例模式的好处。注意:这里的使用python进行SOAP调用。
示例代码:
from zeep.plugins import HistoryPlugin
from shared import Singleton
import zeep
class MySoapClient(metaclass=Singleton):
"""MyFancySoapClient"""
def __init__(
self,
user: str = "username",
password: str = "password",
wsdl: str = "wsdl_url_goes_here",
):
self._history = HistoryPlugin()
self._soap_client = zeep.Client(wsdl, plugins=[self._history])
def methodA():
resp = self._soap_client.ServiceA(
body
)
return resp
def methodB():
resp = self._soap_client.ServiceB(
body
)
return resp
def methodC(request_proxy_url):
self._soap_client.transport.session.proxies = {"https": request_proxy_url}
resp = self._soap_client.ServiceE(
body
)
return resp
def methodD():
resp = self._soap_client.ServiceC(
body
)
return resp
def methodE():
resp = self._soap_client.ServiceD(
body
)
return resp
client = MySoapClient()
client.methodA()
client.methodB()
client.methodC("https://example.com") <---- after this call it modifies the '_soap_client' attribute
client.methodD()
client.methodE()这就是为什么methodD()和methodE()由于添加了self._soap_client.transport.session.proxies而受到影响的原因,实际上,我只需要为methodC()设置代理URL,但是由于单例,它还将更新的属性值传播到mothodD()和methodE()。最后,使我的methodD()和methodE()失败,因为这些方法中的SOAP调用不需要用于代理。
发布于 2022-05-25 17:35:13
您可以将methodC重写为:
def methodC(request_proxy_url):
original_proxies = self._soap_client.transport.session.proxies
self._soap_client.transport.session.proxies = {"https": request_proxy_url}
resp = self._soap_client.ServiceE(
body
)
self._soap_client.transport.session.proxies = original_proxies
return resp(对于在发出请求之前需要修改self._soap_client实例设置的任何其他方法,请执行类似的操作)
我对执行单例模式有点怀疑,而不只是在模块中创建全局变量并从任何地方导入.但这只是个人品味,与你的问题无关。
我认为,了解SOAP的本质,zeep.Client实例是一个相当沉重的对象,因此,如果您能够避免使用多个实例,那么尝试避免多个实例是完全有意义的。
如果您使用多线程平台(例如,使用gevent的Python ),那么您必须小心避免全局vars改变它们的共享状态,就像MySoapClient现在所做的那样。
另一种方法是维护少量不同的zeep.Client实例,并为每个methodA、methodC等使用适当的_soap_client实例。类似于:
class MySoapClient(metaclass=Singleton):
"""MyFancySoapClient"""
def __init__(
self,
user: str = "username",
password: str = "password",
wsdl: str = "wsdl_url_goes_here",
request_proxy_url: str = "default value",
):
self._history = HistoryPlugin()
self._soap_client = zeep.Client(wsdl, plugins=[self._history])
self._soap_client_proxied = zeep.Client(wsdl, plugins=[self._history])
self._soap_client_proxied.transport.session.proxies = {"https": request_proxy_url}
def methodB():
resp = self._soap_client.ServiceB(
body
)
return resp
def methodC(request_proxy_url):
request_proxy_url}
resp = self._soap_client_proxied.ServiceE(
body
)
return resp
# etchttps://stackoverflow.com/questions/72380753
复制相似问题