跳至内容

带帮助的 CLI 参数

入门部分,你了解了如何通过将帮助添加到函数的 文档字符串 中来添加 CLI 应用程序/命令的帮助。

以下是上一个示例的外观

import typer


def main(name: str, lastname: str = "", formal: bool = False):
    """
    Say hi to NAME, optionally with a --lastname.

    If --formal is used, say hi very formally.
    """
    if formal:
        print(f"Good day Ms. {name} {lastname}.")
    else:
        print(f"Hello {name} {lastname}")


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

现在你已经知道如何使用 typer.Argument(),让我们使用它来添加特定于CLI 参数的文档。

CLI 参数添加help文本

你可以使用 help 参数为CLI 参数添加帮助文本

import typer
from typing_extensions import Annotated


def main(name: Annotated[str, typer.Argument(help="The name of the user to greet")]):
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(name: str = typer.Argument(..., help="The name of the user to greet")):
    print(f"Hello {name}")


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

它将用于自动 --help 选项

$ python main.py --help

// Check the section with Arguments below 🚀
Usage: main.py [OPTIONS] NAME

Arguments:
  NAME  The name of the user to greet  [required]

Options:
  --help                Show this message and exit.

合并帮助文本和文档字符串

当然,您还可以将该 help文档字符串 结合使用

import typer
from typing_extensions import Annotated


def main(name: Annotated[str, typer.Argument(help="The name of the user to greet")]):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(name: str = typer.Argument(..., help="The name of the user to greet")):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

--help 选项将合并所有信息

$ python main.py --help

// Notice that we have the help text from the docstring and also the Arguments 📝
Usage: main.py [OPTIONS] NAME

  Say hi to NAME very gently, like Dirk.

Arguments:
  NAME  The name of the user to greet  [required]

Options:
  --help                Show this message and exit.

帮助使用默认值

如果您有一个具有默认值(如 "World")的CLI 参数

import typer
from typing_extensions import Annotated


def main(name: Annotated[str, typer.Argument(help="Who to greet")] = "World"):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(name: str = typer.Argument("World", help="Who to greet")):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

它将在帮助文本中显示该默认值

$ python main.py --help

// Notice the [default: World] 🔍
Usage: main.py [OPTIONS] [NAME]

  Say hi to NAME very gently, like Dirk.

Arguments:
  [NAME]  Who to greet  [default: World]

Options:
  --help                Show this message and exit.

但如果您愿意,可以使用 show_default=False 禁用它

import typer
from typing_extensions import Annotated


def main(
    name: Annotated[
        str, typer.Argument(help="Who to greet", show_default=False)
    ] = "World",
):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(name: str = typer.Argument("World", help="Who to greet", show_default=False)):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

然后它将不会显示默认值

$ python main.py --help

// Notice the there's no [default: World] now 🔥
Usage: main.py [OPTIONS] [NAME]

  Say hi to NAME very gently, like Dirk.

Arguments:
  [NAME]  Who to greet

Options:
  --help                Show this message and exit.

技术细节

在 Click 应用程序中,默认值默认情况下是隐藏的。🙈

Typer 中,这些默认值默认情况下是显示的。👀

自定义默认字符串

您可以使用相同的 show_default 传递自定义字符串(而不是 bool)以自定义要在帮助文本中显示的默认值

import typer
from typing_extensions import Annotated


def main(
    name: Annotated[
        str,
        typer.Argument(
            help="Who to greet", show_default="Deadpoolio the amazing's name"
        ),
    ] = "Wade Wilson",
):
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(
    name: str = typer.Argument(
        "Wade Wilson", help="Who to greet", show_default="Deadpoolio the amazing's name"
    ),
):
    print(f"Hello {name}")


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

它将用于帮助文本

$ python main.py --help

Usage: main.py [OPTIONS] [NAME]

Arguments:
  [NAME]  Who to greet  [default: (Deadpoolio the amazing's name)]


Options:
  --help                Show this message and exit.

// See it shows "(Deadpoolio the amazing's name)" instead of the actual default of "Wade Wilson"

自定义帮助名称 (metavar)

您还可以自定义在生成的帮助文本中用于表示CLI 参数的文本。

默认情况下,它将是您声明的相同名称,以大写字母表示。

因此,如果您将其声明为

name: str

它将显示为

NAME

但是,您可以使用 typer.Argument()metavar 参数对其进行自定义。

例如,假设您不想要 NAME 的默认值,您想要小写的 username,并且您真的想在所有地方使用 ✨ 表情符号 ✨

import typer
from typing_extensions import Annotated


def main(name: Annotated[str, typer.Argument(metavar="✨username✨")] = "World"):
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(name: str = typer.Argument("World", metavar="✨username✨")):
    print(f"Hello {name}")


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

现在,生成的帮助文本将包含 ✨username✨ 而不是 NAME

$ python main.py --help

Usage: main.py [OPTIONS] ✨username✨

Arguments:
  ✨username✨  [default: World]

Options:
  --help                Show this message and exit.

CLI 参数帮助面板

在使用 --help 选项时,您可能希望在不同的面板中显示CLI 参数的帮助信息。

如果您已按照 打印和颜色 文档中所述安装 Rich,则可以将 rich_help_panel 参数设置为您希望显示此CLI 参数的面板的名称

import typer
from typing_extensions import Annotated


def main(
    name: Annotated[str, typer.Argument(help="Who to greet")],
    lastname: Annotated[
        str, typer.Argument(help="The last name", rich_help_panel="Secondary Arguments")
    ] = "",
    age: Annotated[
        str,
        typer.Argument(help="The user's age", rich_help_panel="Secondary Arguments"),
    ] = "",
):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(
    name: str = typer.Argument(..., help="Who to greet"),
    lastname: str = typer.Argument(
        "", help="The last name", rich_help_panel="Secondary Arguments"
    ),
    age: str = typer.Argument(
        "", help="The user's age", rich_help_panel="Secondary Arguments"
    ),
):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

然后,如果您选中 --help 选项,您将看到一个名为“参数”的默认面板,用于没有自定义 rich_help_panelCLI 参数

然后,您将看到其他面板,用于在 rich_help_panel 参数中设置了自定义面板的CLI 参数

$ python main.py --help

<b> </b><font color="#F4BF75"><b>Usage: </b></font><b>main.py [OPTIONS] NAME [LASTNAME] [AGE]               </b>
<b>                                                                     </b>
 Say hi to NAME very gently, like Dirk.

<font color="#A5A5A1">╭─ Arguments ───────────────────────────────────────────────────────╮</font>
<font color="#A5A5A1">│ </font><font color="#F92672">*</font>    name      <font color="#F4BF75"><b>TEXT</b></font>  Who to greet [default: None] <font color="#A6194C">[required]</font>      │
<font color="#A5A5A1">╰───────────────────────────────────────────────────────────────────╯</font>
<font color="#A5A5A1">╭─ Secondary Arguments ─────────────────────────────────────────────╮</font>
<font color="#A5A5A1">│   lastname      </font><font color="#A37F4E"><b>[LASTNAME]</b></font>  The last name                         │
<font color="#A5A5A1">│   age           </font><font color="#A37F4E"><b>[AGE]     </b></font>  The user&apos;s age                        │
<font color="#A5A5A1">╰───────────────────────────────────────────────────────────────────╯</font>
<font color="#A5A5A1">╭─ Options ─────────────────────────────────────────────────────────╮</font>
<font color="#A5A5A1">│ </font><font color="#A1EFE4"><b>--help</b></font>                        Show this message and exit.         │
<font color="#A5A5A1">╰───────────────────────────────────────────────────────────────────╯</font>

在此示例中,我们有一个名为“辅助参数”的自定义CLI 参数面板。

使用 Rich 帮助样式

在未来的部分中,您将看到如何在阅读命令 - 命令帮助时在CLI 参数help 中使用自定义标记。

如果您很赶,可以跳到那里,但除此之外,最好继续在此处阅读并按顺序学习教程。

从帮助文本中隐藏CLI 参数

如果您愿意,您可以让CLI 参数显示在帮助文本的 参数 部分中。

您通常可能不想这样做,但这是可能的

import typer
from typing_extensions import Annotated


def main(name: Annotated[str, typer.Argument(hidden=True)] = "World"):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

提示

如果可能,优先使用 Annotated 版本。

import typer


def main(name: str = typer.Argument("World", hidden=True)):
    """
    Say hi to NAME very gently, like Dirk.
    """
    print(f"Hello {name}")


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

检查它

$ python main.py --help

// Notice there's no Arguments section at all 🔥
Usage: main.py [OPTIONS] [NAME]

  Say hi to NAME very gently, like Dirk.

Options:
  --help                Show this message and exit.

信息

请记住,CLI 参数仍会显示在带有 用法 的第一行中。

但它不会显示在 参数 部分下的主要帮助文本中。

Click 中CLI 参数的帮助文本

Click 本身不支持为CLI 参数添加帮助,并且不会为它们生成帮助,如上面的示例中的“参数:”部分中所示。

不支持CLI 参数中的 help 是 Click 中的故意设计决策

这是为了遵循 Unix 工具的一般惯例,仅对最必要的事物使用参数,并通过按名称引用它们在命令帮助文本中记录它们。

因此,在 Click 应用程序中,您需要在文档字符串中手动编写CLI 参数的所有文档。


尽管如此,Typer 支持 CLI 参数help。✨ 🤷‍♂

Typer 不遵循该惯例,而是支持 help,以便更容易地为 CLI 程序提供格式一致的帮助文本。🎨

这也有助于你创建默认情况下 ✨ 令人惊叹 ✨ 的 CLI 程序。代码极少。

如果你想在 Typer 应用中保留 Click 的惯例,你可以使用上面描述的 hidden 参数来实现。

技术细节

为了在 CLI 参数 中支持 helpTyper 在其 Click 内部类的子类中做了大量内部工作。