You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

argparse子命令行可用但测试时报AttributeError问题

问题解决:argparse子命令参数在测试中报错AttributeError

问题原因

你在list方法内部用argparse定义了可选的query参数,命令行运行时因为传入了list子命令,argparse能正常解析出query(不传时为None);但直接调用Handler().list()的测试用例里,sys.argv没有list这个子命令参数,导致argparse未触发该子命令的参数解析,返回的Namespace对象里根本没有query属性,所以执行if args.query:时会报错。

解决方案

方案一:测试时补全sys.argv参数

在测试用例中通过patch修改sys.argv,补上list子命令,让argparse能正常解析出query参数(值为None):

def test_basic(self):
    """Test that list command prints correct string."""
    with patch("todo.open", mock_open(read_data="One\nTwo\n")), patch('sys.argv', ['file.py', 'list']):
        Handler().list()
    expected = dedent(
        """\
        1 One
        2 Two
        ---
        2 item(s)
        """
    )
    self.assertPrinted(expected)

方案二:重构代码分离职责(推荐)

把命令行解析逻辑和业务逻辑分开,让list方法直接接受query参数,不再依赖argparse从命令行读取:

1. 修改Handler的list方法

def list(self, query=None):
    # 原来的业务逻辑直接使用query参数
    if query:
        # 处理带查询条件的逻辑
        ...
    else:
        # 处理无查询条件的逻辑
        ...

2. 在脚本入口处理argparse解析

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest="command")
    parser_list = subparsers.add_parser("list")
    parser_list.add_argument('query', type=str, nargs='?')
    args = parser.parse_args()

    handler = Handler()
    if args.command == "list":
        handler.list(args.query)

这样测试时直接调用Handler().list()即可,无需关心命令行参数,代码结构更清晰,测试也更简便。

内容的提问来源于stack exchange,提问作者Bloop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:55:10