我正在编写一个学习Python的小脚本。该脚本打印了一个N个玩家的国际象棋锦标赛表。它有一个简单的CLI,带有一个参数N。现在我尝试以下方法:
import argparse
def parse_args(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Tournament tables")
parser.add_argument('N', help="number of players (2 at least)", type=int)
args = parser.parse_args(argv)
if args.N < 2:
parser.error("N must be 2 at least")
return args.N
def main(n: int) -> None:
print(F"Here will be the table for {n} players")
if __name__ == '__main__':
main(parse_args())
但这似乎有一个缺陷。函数main
不检查n
的无效输入(因为这是CLI解析器的工作)。因此,如果有人直接从另一个模块(例如测试器)调用main
,他可能会用0来调用它,程序很可能会崩溃。
我应该如何妥善处理这个问题?
我正在考虑几种可能的方法,但不能肯定哪种是最好的。
1.在main
中添加一个适当的值检查和错误处理。这个选项在我看来很难看,因为它违反了DRY原则,并迫使main
将CLI的工作增加了一倍。
1.只需证明main
必须只取n〉= 2,否则它的行为是不可预测的。可以合并对main
添加Assert检查,如下所示:assert n >= 2, "n must be 2 or more"
1.也许这样一个函数根本不应该是外部的?所以整个选择的习惯用法是错误的,脚本的入口点应该以另一种方式重写。
1.你说什么?
3条答案
按热度按时间chy5wohz1#
你可以让
main
做所有的检查,如果有什么不对的地方,就引发ArgumentError
。然后捕获这个异常并将其转发给解析器显示。大致如下:如果您不想向
main
的库用户公开argparse.ArgumentError
,也可以创建一个自定义异常类型来代替它。hjzp0vay2#
当需要测试函数/CLI时,运行argparse的一种常见方法是让
main
函数获取sys.argv
列表,然后从main
中调用parse_args
,如下所示:这样,测试就可以使用假设的CLI调用main:
hs1rzwqc3#
我一直在使用Pydantic来强制运行时的数据类型化,* 在我的代码中 *。
它是一个非常健壮、使用非常广泛的库,而且速度非常快,因为它更像是一个数据接收验证器,而不是类型检查器。
你可以编写如下的调用,如何调用main完全取决于你:直接调用,argparse,单击...
Pydantic还可以为您提供信息丰富的错误消息,如果不是真正的最终用户友好的话。