跳至内容

终止

在某些情况下,您可能希望在某个时刻终止命令,并停止所有后续执行。

可能是您的代码确定程序已成功完成,也可能是操作已中止。

Exit CLI 程序

您通常可以只让 CLI 程序的代码完成其执行,但在某些情况下,您可能希望在执行过程中的某个时刻终止它。并阻止任何后续代码运行。

这并不一定意味着存在错误,只是不需要执行其他操作。

在这种情况下,您可以引发 typer.Exit() 异常

import typer

existing_usernames = ["rick", "morty"]


def maybe_create_user(username: str):
    if username in existing_usernames:
        print("The user already exists")
        raise typer.Exit()
    else:
        print(f"User created: {username}")


def send_new_user_notification(username: str):
    # Somehow send a notification here for the new user, maybe an email
    print(f"Notification sent for new user: {username}")


def main(username: str):
    maybe_create_user(username=username)
    send_new_user_notification(username=username)


if __name__ == "__main__":
    typer.run(main)

在此示例中,有几件事需要注意。

  • CLI 程序的函数是 main(),而不是其他函数。这是接收CLI 参数的函数。
  • 函数 maybe_create_user() 可以通过抛出 typer.Exit() 来终止程序。
  • 如果程序被 maybe_create_user() 终止,则 send_new_user_notification() 永远不会在 main() 中执行。

检查它

$ python main.py Camila

User created: Camila
Notification sent for new user: Camila

// Try with an existing user
$ python main.py rick

The user already exists

// Notice that the notification code was never run, the second message is not printed

提示

即使你抛出了异常,也不一定意味着有错误。

之所以使用异常,是因为它可以作为“错误”并停止所有执行。

但随后 Typer(实际上是 Click)会捕获它,并正常终止程序。

以错误退出

typer.Exit() 接受一个可选的 code 参数。默认情况下,code0,表示没有错误。

你可以传递一个非 0code 来告诉终端程序执行过程中出现了错误。

import typer


def main(username: str):
    if username == "root":
        print("The root user is reserved")
        raise typer.Exit(code=1)
    print(f"New user created: {username}")


if __name__ == "__main__":
    typer.run(main)

检查它

$ python main.py Camila

New user created: Camila

// Print the result code of the last program executed
$ echo $?

0

// Now make it exit with an error
$ python main.py root

The root user is reserved

// Print the result code of the last program executed
$ echo $?

1

// 1 means there was an error, 0 means no errors.

提示

错误代码可能被其他程序(例如 Bash 脚本)使用,这些程序执行你的 CLI 程序。

中止

有一个特殊的异常可以用来“中止”程序。

它的工作原理与 typer.Exit() 几乎相同,但会将 "Aborted!" 打印到屏幕上,并且在某些情况下可能在稍后有用,以明确表明执行被中止了。

import typer


def main(username: str):
    if username == "root":
        print("The root user is reserved")
        raise typer.Abort()
    print(f"New user created: {username}")


if __name__ == "__main__":
    typer.run(main)

检查它

$ python main.py Camila

New user created: Camila

// Now make it exit with an error
$ python main.py root

The root user is reserved
Aborted!