Requests项目如何使用pytest进行单元测试

前言

Pytest是python的单元测试框架,简单易用,在很多知名项目中应用。requests是python知名的http爬虫库,同样简单易用,是python开源项目的TOP10。关于这2个项目,之前都有过介绍,本文主要介绍requests项目如何使用pytest进行单元测试,希望达到下面3个目标:

  1. 熟练pytest的使用
  2. 学习如何对项目进行单元测试
  3. 深入requests的一些实现细节

本文分如下几个部分:

  • requests项目单元测试状况
  • 简单工具类如何测试
  • request-api如何测试
  • 底层API测试

requests项目单元测试状况

requests的单元测试代码全部在 tests 目录,使用 pytest.ini 进行配置。测试除pytest外,还需要安装:

上述依赖 master 版本在requirement-dev文件中定义;2.24.0版本会在pipenv中定义。

测试用例使用make命令,子命令在Makefile中定义, 使用make ci运行所有单元测试结果如下:

$ make ci
pytest tests --junitxml=report.xml
======================================================================================================= test session starts =======================================================================================================
platform linux -- Python 3.6.8, pytest-3.10.1, py-1.10.0, pluggy-0.13.1
rootdir: /home/work6/project/requests, inifile: pytest.ini
plugins: mock-2.0.0, httpbin-1.0.0, cov-2.9.0
collected 552 items                                                                                                                                                                                                               tests/test_help.py ...                                                                                                                                                                                                      [  0%]
tests/test_hooks.py ...                                                                                                                                                                                                     [  1%]
tests/test_lowlevel.py ...............                                                                                                                                                                                      [  3%]
tests/test_packages.py ...                                                                                                                                                                                                  [  4%]
tests/test_requests.py .................................................................................................................................................................................................... [ 39%]
127.0.0.1 - - [10/Aug/2021 08:41:53] "GET /stream/4 HTTP/1.1" 200 756
.127.0.0.1 - - [10/Aug/2021 08:41:53] "GET /stream/4 HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 46048)
Traceback (most recent call last):File "/usr/lib64/python3.6/wsgiref/handlers.py", line 138, in runself.finish_response()
x.........................................................................................                                                                                                                                 [ 56%]
tests/test_structures.py ....................                                                                                                                                                                               [ 59%]
tests/test_testserver.py ......s....                                                                                                                                                                                        [ 61%]
tests/test_utils.py ..s................................................................................................................................................................................................ssss [ 98%]
ssssss.....                                                                                                                                                                                                                 [100%]----------------------------------------------------------------------------------- generated xml file: /home/work6/project/requests/report.xml -----------------------------------------------------------------------------------
======================================================================================= 539 passed, 12 skipped, 1 xfailed in 64.16 seconds ========================================================================================

可以看到requests在1分钟内,总共通过了539个测试用例,效果还是不错。使用 make coverage 查看单元测试覆盖率:

$ make coverage
----------- coverage: platform linux, python 3.6.8-final-0 -----------
Name                          Stmts   Miss  Cover
-------------------------------------------------
requests/__init__.py             71     71     0%
requests/__version__.py          10     10     0%
requests/_internal_utils.py      16      5    69%
requests/adapters.py            222     67    70%
requests/api.py                  20     13    35%
requests/auth.py                174     54    69%
requests/certs.py                 4      4     0%
requests/compat.py               47     47     0%
requests/cookies.py             238    115    52%
requests/exceptions.py           35     29    17%
requests/help.py                 63     19    70%
requests/hooks.py                15      4    73%
requests/models.py              455    119    74%
requests/packages.py             16     16     0%
requests/sessions.py            283     67    76%
requests/status_codes.py         15     15     0%
requests/structures.py           40     19    52%
requests/utils.py               465    170    63%
-------------------------------------------------
TOTAL                          2189    844    61%
Coverage XML written to file coverage.xml

结果显示requests项目总体覆盖率61%,每个模块的覆盖率也清晰可见。

单元测试覆盖率使用代码行数进行判断,Stmts显示模块的有效行数,Miss显示未执行到的行。如果生成html的报告,还可以定位到具体未覆盖到的行;pycharm的coverage也有类似功能。

tests下的文件及测试类如下表:

 简单工具类如何测试

test_help 实现分析

先从最简单的test_help上手,测试类和被测试对象命名是对应的。先看看被测试的模块help.py。这个模块主要是2个函数 info 和 _implementation:

import idnadef _implementation():...def info():...system_ssl = ssl.OPENSSL_VERSION_NUMBERsystem_ssl_info = {'version': '%x' % system_ssl if system_ssl is not None else ''}idna_info = {'version': getattr(idna, '__version__', ''),}...return {'platform': platform_info,'implementation': implementation_info,'system_ssl': system_ssl_info,'using_pyopenssl': pyopenssl is not None,'pyOpenSSL': pyopenssl_info,'urllib3': urllib3_info,'chardet': chardet_info,'cryptography': cryptography_info,'idna': idna_info,'requests': {'version': requests_version,},}

info提供系统环境的信息,_implementation是其内部实现,以下划线*_*开头。再看测试类test_help:

from requests.help import infodef test_system_ssl():"""Verify we're actually setting system_ssl when it should be available."""assert info()['system_ssl']['version'] != ''class VersionedPackage(object):def __init__(self, version):self.__version__ = versiondef test_idna_without_version_attribute(mocker):"""Older versions of IDNA don't provide a __version__ attribute, verifythat if we have such a package, we don't blow up."""mocker.patch('requests.help.idna', new=None)assert info()['idna'] == {'version': ''}def test_idna_with_version_attribute(mocker):"""Verify we're actually setting idna version when it should be available."""mocker.patch('requests.help.idna', new=VersionedPackage('2.6'))assert info()['idna'] == {'version': '2.6'}

首先从头部的导入信息可以看到,仅仅对info函数进行测试,这个容易理解。info测试通过,自然覆盖到_implementation这个内部函数。这里可以得到单元测试的第1个技巧:

  1. 仅对public的接口进行测试

test_idna_without_version_attribute和test_idna_with_version_attribute均有一个mocker参数,这是pytest-mock提供的功能,会自动注入一个mock实现。使用这个mock对idna模块进行模拟

# 模拟空实现
mocker.patch('requests.help.idna', new=None)
# 模拟版本2.6
mocker.patch('requests.help.idna', new=VersionedPackage('2.6'))

可能大家会比较奇怪,这里patch模拟的是 requests.help.idna , 而我们在help中导入的是 inda 模块。这是因为在requests.packages中对inda进行了模块名重定向:

for package in ('urllib3', 'idna', 'chardet'):locals()[package] = __import__(package)# This traversal is apparently necessary such that the identities are# preserved (requests.packages.urllib3.* is urllib3.*)for mod in list(sys.modules):if mod == package or mod.startswith(package + '.'):sys.modules['requests.packages.' + mod] = sys.modules[mod]

使用mocker后,idna的__version__信息就可以进行控制,这样info中的idna结果也就可以预期。那么可以得到第2个技巧:

2.使用mock辅助单元测试

test_hooks 实现分析

我们继续查看hooks如何进行测试:

from requests import hooksdef hook(value):return value[1:]@pytest.mark.parametrize('hooks_list, result', ((hook, 'ata'),([hook, lambda x: None, hook], 'ta'),)
)
def test_hooks(hooks_list, result):assert hooks.dispatch_hook('response', {'response': hooks_list}, 'Data') == resultdef test_default_hooks():assert hooks.default_hooks() == {'response': []}

hooks模块的2个接口default_hooks和dispatch_hook都进行了测试。其中default_hooks是纯函数,无参数有返回值,这种函数最容易测试,仅仅检查返回值是否符合预期即可。dispatch_hook会复杂一些,还涉及对回调函数(hook函数)的调用:

def dispatch_hook(key, hooks, hook_data, **kwargs):"""Dispatches a hook dictionary on a given piece of data."""hooks = hooks or {}hooks = hooks.get(key)if hooks:# 判断钩子函数if hasattr(hooks, '__call__'):hooks = [hooks]for hook in hooks:_hook_data = hook(hook_data, **kwargs)if _hook_data is not None:hook_data = _hook_datareturn hook_data

pytest.mark.parametrize提供了2组参数进行测试。第一组参数hook和ata很简单,hook是一个函数,会对参数裁剪,去掉首位,ata是期望的返回值。test_hooks的response的参数是Data,所以结果应该是ata。第二组参数中的第一个参数会复杂一些,变成了一个数组,首位还是hook函数,中间使用一个匿名函数,匿名函数没有返回值,这样覆盖到 if _hook_data is not None: 的旁路分支。执行过程如下:

  • hook函数裁剪Data首位,剩余ata
  • 匿名函数不对结果修改,剩余ata
  • hook函数继续裁剪ata首位,剩余ta

经过测试可以发现dispatch_hook的设计十分巧妙,使用pipeline模式,将所有的钩子串起来,这是和事件机制不一样的地方。细心的话,我们可以发现 if hooks: 并未进行旁路测试,这个不够严谨,有违我们的第3个技巧:

3.测试尽可能覆盖目标函数的所有分支

test_structures 实现分析

LookupDict的测试用例如下:

class TestLookupDict:@pytest.fixture(autouse=True)def setup(self):"""LookupDict instance with "bad_gateway" attribute."""self.lookup_dict = LookupDict('test')self.lookup_dict.bad_gateway = 502def test_repr(self):assert repr(self.lookup_dict) == "<lookup 'test'>"get_item_parameters = pytest.mark.parametrize('key, value', (('bad_gateway', 502),('not_a_key', None)))@get_item_parametersdef test_getitem(self, key, value):assert self.lookup_dict[key] == value@get_item_parametersdef test_get(self, key, value):assert self.lookup_dict.get(key) == value

可以发现使用setup方法配合@pytest.fixture,给所有测试用例初始化了一个lookup_dict对象;同时pytest.mark.parametrize可以在不同的测试用例之间复用的,我们可以得到第4个技巧:

4.使用pytest.fixture复用被测试对象,使用pytest.mark.parametriz复用测试参数

通过TestLookupDict的test_getitem和test_get可以更直观的了解LookupDict的get和__getitem__方法的作用:

class LookupDict(dict):...def __getitem__(self, key):# We allow fall-through here, so values default to Nonereturn self.__dict__.get(key, None)def get(self, key, default=None):return self.__dict__.get(key, default)
  • get自定义字典,使其可以使用 get 方法获取值
  • __getitem__自定义字典,使其可以使用 [] 符合获取值

CaseInsensitiveDict的测试用例在test_structures和test_requests中都有测试,前者主要是基础测试,后者偏向业务使用层面,我们可以看到这两种差异:

class TestCaseInsensitiveDict:# 类测试def test_repr(self):assert repr(self.case_insensitive_dict) == "{'Accept': 'application/json'}"def test_copy(self):copy = self.case_insensitive_dict.copy()assert copy is not self.case_insensitive_dictassert copy == self.case_insensitive_dictclass TestCaseInsensitiveDict:# 使用方法测试def test_delitem(self):cid = CaseInsensitiveDict()cid['Spam'] = 'someval'del cid['sPam']assert 'spam' not in cidassert len(cid) == 0def test_contains(self):cid = CaseInsensitiveDict()cid['Spam'] = 'someval'assert 'Spam' in cidassert 'spam' in cidassert 'SPAM' in cidassert 'sPam' in cidassert 'notspam' not in cid

借鉴上面的测试方法,不难得出第5个技巧:

5.可以从不同的层面对同一个对象进行单元测试

后面的test_lowlevel和test_requests也应用了这种技巧

utils.py

utils中构建了一个可以写入env的生成器(由yield关键字提供),可以当上下文装饰器使用:

import contextlib
import os@contextlib.contextmanager
def override_environ(**kwargs):save_env = dict(os.environ)for key, value in kwargs.items():if value is None:del os.environ[key]else:os.environ[key] = valuetry:yieldfinally:os.environ.clear()os.environ.update(save_env)

下面是使用方法示例:

# test_requests.pykwargs = {var: proxy
}
# 模拟控制proxy环境变量
with override_environ(**kwargs):proxies = session.rebuild_proxies(prep, {})def rebuild_proxies(self, prepared_request, proxies):  bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy)def should_bypass_proxies(url, no_proxy):...get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper())...

6.涉及环境变量的地方,可以使用上下文装饰器进行模拟多种环境变量

utils测试用例

utils的测试用例较多,我们选择部分进行分析。先看to_key_val_list函数:

# 对象转列表
def to_key_val_list(value):if value is None:return Noneif isinstance(value, (str, bytes, bool, int)):raise ValueError('cannot encode objects that are not 2-tuples')if isinstance(value, Mapping):value = value.items()return list(value)

对应的测试用例TestToKeyValList:

class TestToKeyValList:@pytest.mark.parametrize('value, expected', (([('key', 'val')], [('key', 'val')]),((('key', 'val'), ), [('key', 'val')]),({'key': 'val'}, [('key', 'val')]),(None, None)))def test_valid(self, value, expected):assert to_key_val_list(value) == expecteddef test_invalid(self):with pytest.raises(ValueError):to_key_val_list('string')

重点是test_invalid中使用pytest.raise对异常的处理:

7.使用pytest.raises对异常进行捕获处理

TestSuperLen介绍了几种进行IO模拟测试的方法:

class TestSuperLen:@pytest.mark.parametrize('stream, value', ((StringIO.StringIO, 'Test'),(BytesIO, b'Test'),pytest.param(cStringIO, 'Test',marks=pytest.mark.skipif('cStringIO is None')),))def test_io_streams(self, stream, value):"""Ensures that we properly deal with different kinds of IO streams."""assert super_len(stream()) == 0assert super_len(stream(value)) == 4def test_super_len_correctly_calculates_len_of_partially_read_file(self):"""Ensure that we handle partially consumed file like objects."""s = StringIO.StringIO()s.write('foobarbogus')assert super_len(s) == 0@pytest.mark.parametrize('mode, warnings_num', (('r', 1),('rb', 0),))def test_file(self, tmpdir, mode, warnings_num, recwarn):file_obj = tmpdir.join('test.txt')file_obj.write('Test')with file_obj.open(mode) as fd:assert super_len(fd) == 4assert len(recwarn) == warnings_numdef test_super_len_with_tell(self):foo = StringIO.StringIO('12345')assert super_len(foo) == 5foo.read(2)assert super_len(foo) == 3def test_super_len_with_fileno(self):with open(__file__, 'rb') as f:length = super_len(f)file_data = f.read()assert length == len(file_data)
  • 使用StringIO来模拟IO操作,可以配置各种IO的测试。当然也可以使用BytesIO/cStringIO, 不过单元测试用例一般不关注性能,StringIO简单够用。
  • pytest提供tmpdir的fixture,可以进行文件读写操作测试
  • 可以使用__file__来进行文件的只读测试,__file__表示当前文件,不会产生副作用。

8.使用IO模拟配合进行单元测试

request-api如何测试

requests的测试需要httpbin和pytest-httpbin,前者会启动一个本地服务,后者会安装一个pytest插件,测试用例中可以得到httpbin的fixture,用来操作这个服务的URL。

坦率的讲:这个测试用例内容庞大,达到2500行。看起来是针对各种业务的零散case,我并没有完全理顺其组织逻辑。我选择一些感兴趣的业务进行介绍, 先看TimeOut的测试:

TARPIT = 'http://10.255.255.1'class TestTimeout:def test_stream_timeout(self, httpbin):try:requests.get(httpbin('delay/10'), timeout=2.0)except requests.exceptions.Timeout as e:assert 'Read timed out' in e.args[0].args[0]@pytest.mark.parametrize('timeout', ((0.1, None),Urllib3Timeout(connect=0.1, read=None)))def test_connect_timeout(self, timeout):try:requests.get(TARPIT, timeout=timeout)pytest.fail('The connect() request should time out.')except ConnectTimeout as e:assert isinstance(e, ConnectionError)assert isinstance(e, Timeout)

test_stream_timeout利用httpbin创建了一个延迟10s响应的接口,然后请求本身设置成2s,这样可以收到一个本地timeout的错误。test_connect_timeout则是访问一个不存在的服务,捕获连接超时的错误。

TestRequests都是对requests的业务进程测试,可以看到至少是2种:

class TestRequests:def test_basic_building(self):req = requests.Request()req.url = 'http://kennethreitz.org/'req.data = {'life': '42'}pr = req.prepare()assert pr.url == req.urlassert pr.body == 'life=42'def test_path_is_not_double_encoded(self):request = requests.Request('GET', "http://0.0.0.0/get/test case").prepare()assert request.path_url == '/get/test%20case...def test_HTTP_200_OK_GET_ALTERNATIVE(self, httpbin):r = requests.Request('GET', httpbin('get'))s = requests.Session()s.proxies = getproxies()r = s.send(r.prepare())assert r.status_code == 200ef test_set_cookie_on_301(self, httpbin):s = requests.session()url = httpbin('cookies/set?foo=bar')s.get(url)assert s.cookies['foo'] == 'bar'
  • 对url进行校验,只需要对request进行prepare,这种情况下,请求并未发送,少了网络传输,测试用例会更迅速
  • 需要响应数据的情况,需要使用httbin构建真实的请求-响应数据

底层API测试

testserver构建一个简单的基于线程的tcp服务,这个tcp服务具有__enter__和__exit__方法,还可以当一个上下文环境使用。

class TestTestServer:def test_basic(self):"""messages are sent and received properly"""question = b"success?"answer = b"yeah, success"def handler(sock):text = sock.recv(1000)assert text == questionsock.sendall(answer)with Server(handler) as (host, port):sock = socket.socket()sock.connect((host, port))sock.sendall(question)text = sock.recv(1000)assert text == answersock.close()def test_text_response(self):"""the text_response_server sends the given text"""server = Server.text_response_server("HTTP/1.1 200 OK\r\n" +"Content-Length: 6\r\n" +"\r\nroflol")with server as (host, port):r = requests.get('http://{}:{}'.format(host, port))assert r.status_code == 200assert r.text == u'roflol'assert r.headers['Content-Length'] == '6'

test_basic方法对Server进行基础校验,确保收发双方可以正确的发送和接收数据。先是客户端的sock发送question,然后服务端在handler中判断收到的数据是question,确认后返回answer,最后客户端再确认可以正确收到answer响应。 test_text_response方法则不完整的测试了http协议。按照http协议的规范发送了http请求,Server.text_response_server会回显请求。下面是模拟浏览器的锚点定位不会经过网络传输的testcase:

def test_fragment_not_sent_with_request():"""Verify that the fragment portion of a URI isn't sent to the server."""def response_handler(sock):req = consume_socket_content(sock, timeout=0.5)sock.send(b'HTTP/1.1 200 OK\r\n'b'Content-Length: '+bytes(len(req))+b'\r\n'b'\r\n'+req)close_server = threading.Event()server = Server(response_handler, wait_to_close_event=close_server)with server as (host, port):url = 'http://{}:{}/path/to/thing/#view=edit&token=hunter2'.format(host, port)r = requests.get(url)raw_request = r.contentassert r.status_code == 200headers, body = raw_request.split(b'\r\n\r\n', 1)status_line, headers = headers.split(b'\r\n', 1)assert status_line == b'GET /path/to/thing/ HTTP/1.1'for frag in (b'view', b'edit', b'token', b'hunter2'):assert frag not in headersassert frag not in bodyclose_server.set()

可以看到请求的path是 /path/to/thing/#view=edit&token=hunter2,其中 # 后面的部分是本地锚点,不应该进行网络传输。上面测试用例中,对接收到的响应进行判断,鉴别响应头和响应body中不包含这些关键字。

结合requests的两个层面的测试,我们可以得出第9个技巧:

9.构造模拟服务配合测试

总结

简单小结一下,从requests的单元测试实践中,可以得到下面9个技巧:

  1. 仅对public的接口进行测试
  2. 使用mock辅助单元测试
  3. 测试尽可能覆盖目标函数的所有分支
  4. 使用pytest.fixture复用被测试对象,使用pytest.mark.parametriz复用测试参数
  5. 可以从不同的层面对同一个对象进行单元测试
  6. 涉及环境变量的地方,可以使用上下文装饰器进行模拟多种环境变量
  7. 使用pytest.raises对异常进行捕获处理
  8. 使用IO模拟配合进行单元测试
  9. 构造模拟服务配合测试

最后:下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!【100%无套路免费领取】

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

  全套资料获取方式:点击下方小卡片自行领取即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141824.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

LLM-TAP随笔——有监督微调【深度学习】【PyTorch】【LLM】

文章目录 5、 有监督微调5.1、提示学习&语境学习5.2、高效微调5.3、模型上下文窗口扩展5.4、指令数据构建5.5、开源指令数据集 5、 有监督微调 5.1、提示学习&语境学习 提示学习 完成预测的三个阶段&#xff1a;提示添加、答案搜索、答案映射 提示添加 “[X] 我感到…

苹果Vision Pro头显内置AI芯片

苹果首席执行官蒂姆库克近日在接受采访时确认&#xff0c;备受瞩目的Vision Pro头显将按计划于明年初在美国上市。这款头显被认为是苹果自iPhone以来最重要的产品之一&#xff0c;售价高达3499美元。 蒂姆库克在接受CBS Sunday Morning的采访时透露&#xff0c;他的团队对Visi…

二叉树进阶

目录 1. 二叉搜索树的概念及结构 1.1. 二叉搜索树的概念 1.2. 二叉搜索树的结构样例&#xff1a; 2. 二叉搜索树实现 2.1. insert的非递归实现 2.2. find的非递归实现 2.3. erase的非递归实现 2.3.1. 第一种情况&#xff1a;所删除的节点的左孩子为空 2.3.1.1. 错误的代…

PTE深度了解(一)

目录 PTE模板开始大审查吗&#xff1f;我的模板还能用吗&#xff1f; 使用模版&#xff0c;不会额外扣你分 类型一&#xff08;前20秒说模版&#xff09; 类型二&#xff08;老实巴交&#xff09; 类型三&#xff08;就是都说简单句&#xff09; 1.查重复 2.增加内容分识…

设备自动化系统EAP在晶圆厂的关键作用

在现代晶圆厂中&#xff0c;设备自动化系统&#xff08;Equipment Automation Programming&#xff0c;EAP&#xff09;已经成为了不可或缺的关键要素。EAP系统不仅是生产自动化的重要组成部分&#xff0c;更是连接制造执行系统&#xff08;MES&#xff09;与设备之间的桥梁&am…

XUI - 一个简洁而优雅的Android原生UI框架

官网 GitHub - xuexiangjys/XUI: &#x1f48d;A simple and elegant Android native UI framework, free your hands! (一个简洁而优雅的Android原生UI框架&#xff0c;解放你的双手&#xff01;) XUI | &#x1f48d;A simple and elegant Android native UI framework, fre…

OpenCV项目开发实战--主成分分析(PCA)的特征脸应用(附C++/Python实现源码)

什么是主成分分析? 这是理解这篇文章的先决条件。 图 1:使用蓝线和绿线显示 2D 数据的主要组成部分(红点)。 快速回顾一下,我们了解到第一个主成分是数据中最大方差的方向。第二主成分是空间中与第一主成分垂直(正交)的最大方差方向,依此类推。第一和第二主成分红点(2…

robotframework在Jenkins执行踩坑

1. Groovy Template file [robot_results.groovy] was not found in $JENKINS_HOME/email_template 1.需要在managed files 添加robot_results.groovy。这个名字需要和配置在构建项目里default content一致&#xff08;Extended E-mail Notification默认设置里Default Content…

一文搞懂UART通信协议

目录 1、UART简介 2、UART特性 3、UART协议帧 3.1、起始位 3.2、数据位 3.3、奇偶校验位 3.4、停止位 4、UART通信步骤 1、UART简介 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff0c;通用异步收发器&#xff09;是一种双向、串行、异步的通信…

Python:pyts库中的GramianAngularField

您想要使用pyts库中的GramianAngularField类&#xff0c;这是一个用于时间序列数据图像转换的工具。要使用这个类&#xff0c;首先确保您已经安装了pyts库。如果尚未安装&#xff0c;您可以使用以下命令来安装它&#xff1a; pip install pyts一旦安装完成&#xff0c;您可以通…

基于微信小程序的健身房私教预约平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

力扣刷题-链表-删除链表的倒数第N个节点

19.删除链表的倒数第N个节点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a;输入&#xff1a;head [1], n 1 输出&…

深度学习中什么是embedding

使用One-hot 方法编码的向量会很高维也很稀疏。假设我们在做自然语言处理(NLP)中遇到了一个包含2000个词的字典&#xff0c;当使用One-hot编码时&#xff0c;每一个词会被一个包含2000个整数的向量来表示&#xff0c;其中1999个数字是0&#xff0c;如果字典再大一点&#xff0c…

笔记1-2:

一、磁荷与磁流的引入 麦克斯韦方程组&#xff1a; 引入磁荷和磁流的概念&#xff0c;上述方程可以写成对称形式&#xff1a; 磁荷和磁流实际上不存在&#xff0c;只具有某种等效意义&#xff0c;可以把某个区域中的电磁场看成是由一组等效磁型源所产生。 对于均匀和各向同性…

PHP8的类与对象的基本操作之成员变量-PHP8知识详解

成员变量是指在类中定义的变量。在类中可以声明多个变量&#xff0c;所以对象中可以存在多个成员变量&#xff0c;每个变量将存储不同的对象属性信息。 例如以下定义&#xff1a; public class Goods { 关键字 $name; //类的成员变量 }成员属性必须使用关键词进行修饰&#xf…

LRU、LFU 内存淘汰算法的设计与实现

1、背景介绍 LRU、LFU都是内存管理淘汰算法&#xff0c;内存管理是计算机技术中重要的一环&#xff0c;也是多数操作系统中必备的模块。应用场景&#xff1a;假设 给定你一定内存空间&#xff0c;需要你维护一些缓存数据&#xff0c;LRU、LFU就是在内存已经满了的情况下&#…

负载均衡器监控

什么是负载均衡器 负载均衡建立在现有网络结构之上&#xff0c;它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。其意思就是分摊到多个操作单元上进行执行&#xff0c;例如Web服务器、FTP服务器、企…

华为存储培训

01 存储前沿技术和发展趋势 狭义的存储定义 CD、DVD、ZIP、磁带、硬盘等 广义的存储定义 存储硬件系统&#xff08;磁盘阵列&#xff0c;控制器&#xff0c;磁盘柜&#xff0c;磁带库等&#xff09; 存储软件&#xff08;备份软件&#xff1b;管理软件&#xff0c;快照&…

Supervisor进程管理

Supervisor进程管理 概述&#xff1a;supervisor 是一个用 python 语言编写的进程管理工具&#xff0c;它可以很方便的监听、启动、停止、重启一个或多个进程。当一个进程意外被杀死&#xff0c;supervisor 监听到进程死后&#xff0c;可以很方便的让进程自动恢复&#xff0c;…

Linux查看哪些进程占用的系统 buffer/cache 较高 (hcache,lsof)命令

1、什么是buffer/cache &#xff1f; buffer/cache 其实是作为服务器系统的文件数据缓存使用的&#xff0c;尤其是针对进程对文件存在 read/write 操作的时候&#xff0c;所以当你的服务进程在对文件进行读写的时候&#xff0c;Linux内核为了提高服务的读写速度&#xff0c;则将…