我正在修改一些代码,使之兼容Python 2
和Python 3
,但是在单元测试输出中观察到了一个警告。
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/case.py:601:
ResourceWarning: unclosed socket.socket fd=4,
family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6,
laddr=('1.1.2.3', 65087), raddr=('5.8.13.21', 8080)
经过一番研究,发现这个问题也出现在流行的库中,比如requests和boto3。
我可以忽略此警告或完全过滤掉它。如果是我的服务,我可以在响应中设置connection: close
头信息(链接)。
以下是一个在Python 3.6.1
中显示警告的示例:
app.py
import requests
class Service(object):
def __init__(self):
self.session = requests.Session()
def get_info(self):
uri = 'http://api.stackexchange.com/2.2/info?site=stackoverflow'
response = self.session.get(uri)
if response.status_code == 200:
return response.json()
else:
response.raise_for_status()
def __del__(self):
self.session.close()
if __name__ == '__main__':
service = Service()
print(service.get_info())
test.py
import unittest
class TestService(unittest.TestCase):
def test_growing(self):
import app
service = app.Service()
res = service.get_info()
self.assertTrue(res['items'][0]['new_active_users'] > 1)
if __name__ == '__main__':
unittest.main()
有没有更好/正确的方法来管理会话,以便明确关闭它,并且不依赖__del__()
来导致这种警告。
感谢任何帮助。
close
方法,该方法将委托给底层资源的close
方法。更好的做法是让您的类实现上下文管理器协议,然后在with
语句中使用它(__exit__
方法只需调用您的close
方法,而__enter__
方法可以简单地返回self
,因此额外的工作不多)。 - ShadowRanger