解密Python中的*args和**kwargs函数

本文详细介绍了Python编程中的*args和**kwargs概念,包括其用法、示例代码,并展示了在接口自动化测试中的应用场景,如参数传递、断言和动态数据生成。

在Python编程中,*args和**kwargs是两个常用的函数参数形式,它们提供了灵活性和扩展性,使函数能够处理不定数量的参数。本文将详细解释*args和**kwargs的概念、用法以及在实际接口自动化工作中的示例代码。

*args的使用

*args是一个特殊的参数,表示接受任意数量的位置参数。

在函数定义时,可以使用*args作为参数名,它会将传入的位置参数打包成一个元组。

函数内部可以通过遍历元组或使用索引来访问这些位置参数。

示例代码:


def print_args(*args):
    for arg in args:
        print(arg)
print_args("Hello", "World", 2022)  # 输出:Hello World 2022

同时,我也为大家准备了一份软件测试视频教程(含面试、接口、自动化、性能测试等),就在下方,需要的可以直接去观看,也可以直接点击文末小卡片免费领取资料文档

软件测试视频教程观看处:

B站封神的接口测试教程,30天练完70个项目实战(含自动化测试、性能测试),学完即就业,永久白嫖!

**kwargs的使用

**kwargs是一个特殊的参数,表示接受任意数量的关键字参数。

在函数定义时,可以使用**kwargs作为参数名,它会将传入的关键字参数打包成一个字典。

函数内部可以通过字典的键值对来访问这些关键字参数。

示例代码:


def print_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
print_kwargs(name="Alice", age=25)  # 输出:name: Alice, age: 25

*args和**kwargs的组合使用

*args和**kwargs可以同时在函数定义中使用,允许接受任意数量的位置参数和关键字参数。

函数调用时,可以同时传递位置参数和关键字参数。

示例代码:​​​​​​​

def print_args_kwargs(*args, **kwargs):
    for arg in args:
        print(arg)
    for key, value in kwargs.items():
        print(f"{key}: {value}")
print_args_kwargs("Hello", "World", name="Alice", age=25)
# 输出:
# Hello
# World
# name: Alice
# age: 25

在实际接口自动化工作中,*args和**kwargs也有很多应用场景。例如,当编写一个通用的请求函数时,可以使用*args和**kwargs来接受不同接口的参数,实现灵活的请求。

示例代码:


import requests
def send_request(url, method="GET", *args, **kwargs):
    if method == "GET":
        response = requests.get(url, *args, **kwargs)
    elif method == "POST":
        response = requests.post(url, *args, **kwargs)
    else:
        raise ValueError("Unsupported method")
    return response
# 调用send_request函数,发送不同类型的请求
response1 = send_request("https://api.example.com/data", params={"id": 1})
response2 = send_request("https://api.example.com/data", method="POST", json={"name": "Alice"})

当进行接口自动化测试时,*args和**kwargs可以用于以下几个方面的应用

发送请求时的参数化

在接口测试中,往往需要传递不同的请求参数,如请求头、查询参数、请求体等。使用*args和**kwargs可以方便地实现参数的动态传递。例如:


import requests
def send_request(url, method="GET", *args, **kwargs):
    response = requests.request(method, url, *args, **kwargs)
    return response
# 调用send_request函数,发送带有请求头和查询参数的GET请求
response = send_request("https://api.example.com/data", headers={"Authorization": "Bearer xxx"}, params={"page": 1})

断言结果的灵活性

在接口自动化测试中,需要对接口返回的结果进行断言。使用*args和**kwargs可以实现对返回结果的灵活性断言。例如:

def assert_response(response, expected_status_code=200, *args, **kwargs):
    assert response.status_code == expected_status_code, "Invalid status code"
    # 其他断言逻辑...
# 调用assert_response函数,对接口返回结果进行断言
assert_response(response, expected_status_code=200, headers={"Content-Type": "application/json"})

动态生成测试数据

在接口自动化测试中,有时需要动态生成测试数据,例如生成随机的用户名、密码等。使用*args和**kwargs可以方便地传递这些动态生成的测试数据。例如:

def generate_user_data(*args, **kwargs):
    # 生成用户名、密码等测试数据
    username = generate_random_username()
    password = generate_random_password()
    # 其他测试数据生成逻辑...
    return username, password
# 调用generate_user_data函数,获取动态生成的测试数据
username, password = generate_user_data()

在接口自动化测试中,有时需要封装一系列的测试步骤,使用*args和**kwargs可以方便地传递不同的测试参数。例如:

def login_and_assert_response(url, username, password, expected_status_code=200, *args, **kwargs):
    # 登录步骤
    login_response = send_login_request(url, username, password)
    assert_response(login_response, expected_status_code=200)
    # 其他测试步骤...
# 调用login_and_assert_response函数,执行登录并断言响应结果
login_and_assert_response("https://api.example.com/login", username="admin", password="password", expected_status_code=200)

总结

通过上述示例,我们可以看到*args和**kwargs在接口自动化测试中的灵活运用。它们可以帮助我们实现参数化、灵活断言、动态生成数据和封装测试步骤等功能,提高测试代码的可维护性和可扩展性。

PS:这里分享一套软件测试的自学教程合集。对于在测试行业发展的小伙伴们来说应该会很有帮助。除了基础入门的资源,博主也收集不少进阶自动化的资源,从理论到实战,知行合一才能真正的掌握。全套内容已经打包到网盘,内容总量接近100个G。

☑ 240集-零基础到精通全套视频课程
☑ [课件+源码]-完整配套的教程
☑ 18套-测试实战项目源码
☑ 37套-测试工具软件包
☑ 268道-真实面试题
☑ 200个模板-面试简历模板、测试方案模板、软件测试报告模板、测试分析模版、测试计划模板、性能测试报告、性能测试报告、性能测试脚本用例模板(信息完整)

这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[2], line 1 ----> 1 elements = partition_pdf( 2 filename="2024发注方针企划书(移动互联)10.31.pdf", 3 # strategy="hi_res", 4 extract_images_in_pdf=True, 5 # extract_image_block_types=["Image", "Table"], 6 infer_table_strategy=True, 7 hi_res_model_name='yolox', 8 languages=['chi_sim'] 9 ) File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/documents/elements.py:585, in process_metadata.<locals>.decorator.<locals>.wrapper(*args, **kwargs) 583 @functools.wraps(func) 584 def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> list[Element]: --> 585 elements = func(*args, **kwargs) 586 call_args = get_call_args_applying_defaults(func, *args, **kwargs) 588 unique_element_ids: bool = call_args.get("unique_element_ids", False) File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/file_utils/filetype.py:811, in add_filetype.<locals>.decorator.<locals>.wrapper(*args, **kwargs) 809 @functools.wraps(func) 810 def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> list[Element]: --> 811 elements = func(*args, **kwargs) 813 for element in elements: 814 # NOTE(robinson) - Attached files have already run through this logic 815 # in their own partitioning function 816 if element.metadata.attached_to_filename is None: File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/file_utils/filetype.py:769, in add_metadata.<locals>.wrapper(*args, **kwargs) 767 @functools.wraps(func) 768 def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> list[Element]: --> 769 elements = func(*args, **kwargs) 770 call_args = get_call_args_applying_defaults(func, *args, **kwargs) 772 if call_args.get("metadata_filename"): File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/chunking/dispatch.py:74, in add_chunking_strategy.<locals>.wrapper(*args, **kwargs) 71 """The decorated function is replaced with this one.""" 73 # -- call the partitioning function to get the elements -- ---> 74 elements = func(*args, **kwargs) 76 # -- look for a chunking-strategy argument -- 77 call_args = get_call_args_applying_defaults(func, *args, **kwargs) File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/partition/pdf.py:228, in partition_pdf(filename, file, include_page_breaks, strategy, infer_table_structure, ocr_languages, languages, metadata_filename, metadata_last_modified, chunking_strategy, hi_res_model_name, extract_images_in_pdf, extract_image_block_types, extract_image_block_output_dir, extract_image_block_to_payload, starting_page_number, extract_forms, form_extraction_skip_tables, password, pdfminer_line_margin, pdfminer_char_margin, pdfminer_line_overlap, pdfminer_word_margin, **kwargs) 225 exactly_one(filename=filename, file=file) 227 languages = check_language_args(languages or [], ocr_languages) --> 228 return partition_pdf_or_image( 229 filename=filename, 230 file=file, 231 include_page_breaks=include_page_breaks, 232 strategy=strategy, 233 infer_table_structure=infer_table_structure, 234 languages=languages, 235 metadata_last_modified=metadata_last_modified, 236 hi_res_model_name=hi_res_model_name, 237 extract_images_in_pdf=extract_images_in_pdf, 238 extract_image_block_types=extract_image_block_types, 239 extract_image_block_output_dir=extract_image_block_output_dir, 240 extract_image_block_to_payload=extract_image_block_to_payload, 241 starting_page_number=starting_page_number, 242 extract_forms=extract_forms, 243 form_extraction_skip_tables=form_extraction_skip_tables, 244 password=password, 245 pdfminer_line_margin=pdfminer_line_margin, 246 pdfminer_char_margin=pdfminer_char_margin, 247 pdfminer_line_overlap=pdfminer_line_overlap, 248 pdfminer_word_margin=pdfminer_word_margin, 249 **kwargs, 250 ) File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/partition/pdf.py:341, in partition_pdf_or_image(filename, file, is_image, include_page_breaks, strategy, infer_table_structure, languages, metadata_last_modified, hi_res_model_name, extract_images_in_pdf, extract_image_block_types, extract_image_block_output_dir, extract_image_block_to_payload, starting_page_number, extract_forms, form_extraction_skip_tables, password, pdfminer_line_margin, pdfminer_char_margin, pdfminer_line_overlap, pdfminer_word_margin, ocr_agent, table_ocr_agent, **kwargs) 339 with warnings.catch_warnings(): 340 warnings.simplefilter("ignore") --> 341 elements = _partition_pdf_or_image_local( 342 filename=filename, 343 file=spooled_to_bytes_io_if_needed(file), 344 is_image=is_image, 345 infer_table_structure=infer_table_structure, 346 include_page_breaks=include_page_breaks, 347 languages=languages, 348 ocr_languages=ocr_languages, 349 metadata_last_modified=metadata_last_modified or last_modified, 350 hi_res_model_name=hi_res_model_name, 351 pdf_text_extractable=pdf_text_extractable, 352 extract_images_in_pdf=extract_images_in_pdf, 353 extract_image_block_types=extract_image_block_types, 354 extract_image_block_output_dir=extract_image_block_output_dir, 355 extract_image_block_to_payload=extract_image_block_to_payload, 356 starting_page_number=starting_page_number, 357 extract_forms=extract_forms, 358 form_extraction_skip_tables=form_extraction_skip_tables, 359 password=password, 360 pdfminer_config=pdfminer_config, 361 ocr_agent=ocr_agent, 362 table_ocr_agent=table_ocr_agent, 363 **kwargs, 364 ) 365 # NOTE(crag): do not call _process_uncategorized_text_elements here, because 366 # extracted elements (which are text blocks outside of OD-determined blocks) 367 # are likely not Titles and should not be identified as such. 368 return elements File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/utils.py:216, in requires_dependencies.<locals>.decorator.<locals>.wrapper(*args, **kwargs) 213 @wraps(func) 214 def wrapper(*args: _P.args, **kwargs: _P.kwargs): 215 run_check() --> 216 return func(*args, **kwargs) File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured/partition/pdf.py:649, in _partition_pdf_or_image_local(filename, file, is_image, infer_table_structure, include_page_breaks, languages, ocr_languages, ocr_mode, model_name, hi_res_model_name, pdf_image_dpi, metadata_last_modified, pdf_text_extractable, extract_images_in_pdf, extract_image_block_types, extract_image_block_output_dir, extract_image_block_to_payload, analysis, analyzed_image_output_dir_path, starting_page_number, extract_forms, form_extraction_skip_tables, pdf_hi_res_max_pages, password, pdfminer_config, ocr_agent, table_ocr_agent, **kwargs) 646 skip_analysis_dump = env_config.ANALYSIS_DUMP_OD_SKIP 648 if file is None: --> 649 inferred_document_layout = process_file_with_model( 650 filename, 651 is_image=is_image, 652 model_name=hi_res_model_name, 653 pdf_image_dpi=pdf_image_dpi, 654 password=password, 655 ) 657 extracted_layout, layouts_links = ( 658 process_file_with_pdfminer( 659 filename=filename, (...) 665 else ([], []) 666 ) 668 if analysis: File ~/anaconda3/envs/py3-11-7/lib/python3.11/site-packages/unstructured_inference/inference/layout.py:386, in process_file_with_model(filename, model_name, is_image, fixed_layouts, extract_tables, pdf_image_dpi, **kwargs) 374 def process_file_with_model( 375 filename: str, 376 model_name: Optional[str], (...) 381 **kwargs, 382 ) -> DocumentLayout: 383 """Processes pdf file with name filename into a DocumentLayout by using a model identified by 384 model_name.""" --> 386 model = get_model(model_name, **kwargs) 387 if isinstance(model, UnstructuredObjectDetectionModel): 388 detection_model = model TypeError: get_model() got an unexpected keyword argument 'password'
最新发布
07-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值