重置类的所有实例的描述符缓存的属性



我希望在多个类实例之间共享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(重置所有其他实例也感觉不完全正确。

那么,我不喜欢connectdisconnect属于不同的类,理想情况下,我希望它们都在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

最新更新