我有以下代码片段让我思考
# Utlizing api_sess from the /token response
# api_sess is a requests.Session() with Authorization header set with session token
products_resp = api_sess.get(
f'{API_BASE}/products',
params = {'type': 'Item'}
)
if products_resp.ok:
while True:
current_page = products_resp.headers.get('X-Current-Page', 1)
total_pages = products_resp.headers.get('X-Total-Pages', 0)
products_json = products_resp.json()
for product in products_json:
print(product['groupCode'], product['sku'], product['productStatus'])
# Handle pagination
if current_page < total_pages:
products_resp = api_sess.get(
f'{API_BASE}/products',
params = {'type': 'Item', 'page': current_page + 1}
)
if not products_resp.ok:
# Break out of while loop before raising error
break
else:
break
# Raise exception outside of while loop to prevent memory leak
if not products_resp.ok:
raise ValueException(f'Request Error {products_resp.status_code}')
else:
raise ValueException(f'Request Error {products_resp.status_code}')
最初,我要去检查下一页请求响应raise
的while
地方的异常,如下所示:
if current_page < total_pages:
products_resp = api_sess.get(
f'{API_BASE}/products',
params = {'type': 'Item', 'page': current_page + 1}
)
if not products_resp.ok:
raise ValueException(f'Request Error {products_resp.status_code}')
else:
break
起初我什么都没想到,但是我开始怀疑是否会进行资源清理,因为while
由于True
条件的限制,错误会在无限循环内引发。因此,为什么我不可避免地要重新设计我的逻辑以首先打破while
循环,然后重新检查响应状态。
我认为,这种谨慎的方法并不像我想要的那样优雅,因为我正在重复检查响应状态。这引出我的问题:
将异常保持在while
循环内是否安全,否则会导致内存泄漏?
我知道这个问题和场景看似微不足道,但是我想尽可能地在各个方面坚持最佳实践。在我进行谷歌搜索时(尽管我没有花费至少几个小时的时间),此问题并未得到有关如何处理此情况的任何适用解释。
无论您是通过return
还是通过未捕获的异常离开当前作用域,该对象上的引用计数都将减少。一个简单的例子:
import sys
a = "hello"
def foo(b):
x = a
print(f'x: {sys.getrefcount(x)}')
if b:
return
else:
raise Exception()
print(f'a: {sys.getrefcount(a)}')
foo(True)
print(f'a: {sys.getrefcount(a)}')
try:
print(f'a: {sys.getrefcount(a)}')
foo(False)
except Exception:
pass
print(f'a: {sys.getrefcount(a)}')
确切的输出可能会有所不同,但是您应注意参考计数x
要比的参考计数大1 a
,后者在调用之前和之后保持不变foo
。
在这两种情况下,全局引用计数a
在foo
调用时都会增加,在foo
退出后(或try
捕获异常的语句完成之后)会减少。如果从未捕获到异常,则解释器仍然退出,从而引起内存泄漏的问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句