终止
在某些情况下,您可能希望在某个时刻终止命令,并停止所有后续执行。
可能是您的代码确定程序已成功完成,也可能是操作已中止。
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
参数。默认情况下,code
为 0
,表示没有错误。
你可以传递一个非 0
的 code
来告诉终端程序执行过程中出现了错误。
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!