布尔型 CLI 选项
我们已经看到了一些使用 bool
的CLI 选项的示例,以及 Typer 如何自动创建 --something
和 --no-something
。
但我们可以自定义这些名称。
仅 --force
¶
假设我们只想要一个 --force
CLI 选项,我们想要丢弃 --no-force
。
我们可以通过指定我们想要的精确名称来做到这一点
import typer
from typing_extensions import Annotated
def main(force: Annotated[bool, typer.Option("--force")] = False):
if force:
print("Forcing operation")
else:
print("Not forcing")
if __name__ == "__main__":
typer.run(main)
提示
如果可能,建议使用Annotated
版本。
import typer
def main(force: bool = typer.Option(False, "--force")):
if force:
print("Forcing operation")
else:
print("Not forcing")
if __name__ == "__main__":
typer.run(main)
现在只有一个--force
CLI 选项
// Check the help
$ python main.py --help
// Notice there's only --force, we no longer have --no-force
Usage: main.py [OPTIONS]
Options:
--force [default: False]
--help Show this message and exit.
// Try it:
$ python main.py
Not forcing
// Now add --force
$ python main.py --force
Forcing operation
// And --no-force no longer exists ⛔️
$ python main.py --no-force
Usage: main.py [OPTIONS]
Try "main.py --help" for help.
Error: No such option: --no-force
备选名称¶
现在让我们假设我们有一个CLI 选项--accept
。
我们希望允许设置--accept
或相反,但--no-accept
看起来很丑。
我们可能希望改为使用--accept
和--reject
。
我们可以通过传递一个包含bool
CLI 选项的两个名称的单个str
,并用/
分隔来做到这一点
from typing import Optional
import typer
from typing_extensions import Annotated
def main(accept: Annotated[Optional[bool], typer.Option("--accept/--reject")] = None):
if accept is None:
print("I don't know what you want yet")
elif accept:
print("Accepting!")
else:
print("Rejecting!")
if __name__ == "__main__":
typer.run(main)
提示
如果可能,建议使用Annotated
版本。
from typing import Optional
import typer
def main(accept: Optional[bool] = typer.Option(None, "--accept/--reject")):
if accept is None:
print("I don't know what you want yet")
elif accept:
print("Accepting!")
else:
print("Rejecting!")
if __name__ == "__main__":
typer.run(main)
检查一下
// Check the help
$ python main.py --help
// Notice the --accept / --reject
Usage: main.py [OPTIONS]
Options:
--accept / --reject
--help Show this message and exit.
// Try it
$ python main.py
I don't know what you want yet
// Now pass --accept
$ python main.py --accept
Accepting!
// And --reject
$ python main.py --reject
Rejecting!
简短名称¶
同样地,您可以为这些CLI 选项声明名称的简短版本。
例如,假设我们想要-f
代表--force
,-F
代表--no-force
import typer
from typing_extensions import Annotated
def main(force: Annotated[bool, typer.Option("--force/--no-force", "-f/-F")] = False):
if force:
print("Forcing operation")
else:
print("Not forcing")
if __name__ == "__main__":
typer.run(main)
提示
如果可能,建议使用Annotated
版本。
import typer
def main(force: bool = typer.Option(False, "--force/--no-force", "-f/-F")):
if force:
print("Forcing operation")
else:
print("Not forcing")
if __name__ == "__main__":
typer.run(main)
检查一下
// Check the help
$ python main.py --help
// Notice the -f, --force / -F, --no-force
Usage: main.py [OPTIONS]
Options:
-f, --force / -F, --no-force [default: False]
--help Show this message and exit.
// Try with the short name -f
$ python main.py -f
Forcing operation
// Try with the short name -F
$ python main.py -F
Not forcing
仅用于False
的名称¶
如果您想(尽管这可能不是一个好主意),您可以只声明CLI 选项名称来设置False
值。
为此,请使用空格和单个/
,并将负名称放在后面
import typer
from typing_extensions import Annotated
def main(in_prod: Annotated[bool, typer.Option(" /--demo", " /-d")] = True):
if in_prod:
print("Running in production")
else:
print("Running demo")
if __name__ == "__main__":
typer.run(main)
提示
如果可能,建议使用Annotated
版本。
import typer
def main(in_prod: bool = typer.Option(True, " /--demo", " /-d")):
if in_prod:
print("Running in production")
else:
print("Running demo")
if __name__ == "__main__":
typer.run(main)
提示
请记住,这是一个以空格开头,然后是/
的字符串。
所以,它是" /-S"
而不是"/-S"
。
检查一下
// Check the help
$ python main.py --help
// Notice the / -d, --demo
Usage: main.py [OPTIONS]
Options:
/ -d, --demo [default: True]
--help Show this message and exit.
// Try it
$ python main.py
Running in production
// Now pass --demo
$ python main.py --demo
Running demo
// And the short version
$ python main.py -d
Running demo