我希望在多个类实例之间共享requests
会话,并能够重置所有此类实例的会话。
因此,我有disconnect
方法来重置所有实例的会话:
import requests
class CachedSession:
def __init__(self):
self._initialized = None
def __get__(self, *args, **kwargs):
if self._initialized is None:
self._initialized = self.connect()
return self._initialized
def connect(self):
session = requests.session()
session.headers = {}
session.proxies = {}
session.verify = False
return session
class SomeApi:
session = CachedSession()
def __init__(self):
self.api_key = '123'
def disconnect(self):
self.__class__.session.close()
self.__class__.session = None
def request(self):
print(f'making request using session ID {id(self.session)}')
some_api1 = SomeApi()
some_api2 = SomeApi()
some_api1.request()
some_api1.request()
some_api2.request()
some_api1.disconnect()
some_api1.request()
some_api1.request()
some_api2.request()
# prints OK:
# making request using session ID 1291988425360
# making request using session ID 1291988425360
# making request using session ID 1291988425360
# making request using session ID 140726378118360
# making request using session ID 140726378118360
# making request using session ID 140726378118360
但这是正确的方法吗?
必须使用__class__
感觉有点麻烦,但如果我删除它,只有实例会话会被重置。
我使用实例方法(disconnect
(重置所有其他实例也感觉不完全正确。
那么,我不喜欢connect
和disconnect
属于不同的类,理想情况下,我希望它们都在CachedSession
描述符上(但我如何调用disconnect
呢?(
要用单例实例实现CachedSession
,您应该将其定义为类属性
必须使用
__class__
感觉有点麻烦,但如果我删除它,只有实例会话会被重置。
您也可以像下面的一样,将方法定义为@classmethod
,而不是__class__
属性
class CachedSession:
_session = None
def __get__(self, *args, **kwargs):
return self.connect()
@classmethod
def connect(cls):
if not cls._session:
cls._session = requests.session()
cls._session.headers = {}
cls._session.proxies = {}
cls._session.verify = False
return cls._session
@classmethod
def disconnect(cls):
if cls._session:
cls._session.close()
cls._session = None
然后我不喜欢connect和disconnect属于不同的类,理想情况下我希望它们都在CachedSession描述符上(但我如何调用disconnect?(
如您所见,disconnect
已经是CachedSession
的@classmethod
,这意味着它可以更改任何类属性以及_session
。因此,在断开会话后,将断开类的所有实例,而__get__
尚未被调用。要断开会话,只需调用CachedSession.disconnect()
。
class SomeApi:
session = CachedSession()
def request(self):
print(f'making request using session ID {id(self.session)}')
some_api1 = SomeApi()
some_api2 = SomeApi()
some_api1.request() # making request using session ID 139839142708616
some_api1.request() # making request using session ID 139839142708616
some_api2.request() # making request using session ID 139839142708616
CachedSession.disconnect()
some_api1.request() # making request using session ID 139839142240040
some_api1.request() # making request using session ID 139839142240040
some_api2.request() # making request using session ID 139839142240040