跳至内容

路径

您可以将CLI 参数声明为标准 Python pathlib.Path

这是您对目录路径、文件路径等的操作方式

from pathlib import Path
from typing import Optional

import typer
from typing_extensions import Annotated


def main(config: Annotated[Optional[Path], typer.Option()] = None):
    if config is None:
        print("No config file")
        raise typer.Abort()
    if config.is_file():
        text = config.read_text()
        print(f"Config file contents: {text}")
    elif config.is_dir():
        print("Config is a directory, will use all its config files")
    elif not config.exists():
        print("The config doesn't exist")


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

提示

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

from pathlib import Path
from typing import Optional

import typer


def main(config: Optional[Path] = typer.Option(None)):
    if config is None:
        print("No config file")
        raise typer.Abort()
    if config.is_file():
        text = config.read_text()
        print(f"Config file contents: {text}")
    elif config.is_dir():
        print("Config is a directory, will use all its config files")
    elif not config.exists():
        print("The config doesn't exist")


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

同样,由于您收到了与类型注释相同的标准 Python Path 对象,因此您的编辑器将为您提供其所有属性和方法的自动完成。

检查一下

// No config
$ python main.py

No config file
Aborted!

// Pass a config that doesn't exist
$ python main.py --config config.txt

The config doesn't exist

// Now create a quick config
$ echo "some settings" > config.txt

// And try again
$ python main.py --config config.txt

Config file contents: some settings

// And with a directory
$ python main.py --config ./

Config is a directory, will use all its config files

路径验证

您可以对PathCLI 参数执行多种验证

  • exists: 如果设置为 true,则文件或目录需要存在才能使此值有效。如果不需要,并且文件确实不存在,则所有后续检查将静默跳过。
  • file_okay: 控制文件是否为可能的值。
  • dir_okay: 控制目录是否为可能的值。
  • writable: 如果为 true,则执行可写检查。
  • readable: 如果为 true,则执行可读检查。
  • resolve_path: 如果为 true,则在将值传递之前完全解析路径。这意味着它是绝对的,并且 符号链接 被解析。

技术细节

它不会扩展波浪号前缀(带有 ~ 的东西,例如 ~/Documents/),因为这应该只由 shell 完成。

提示

所有这些参数都直接来自 Click

例如

from pathlib import Path

import typer
from typing_extensions import Annotated


def main(
    config: Annotated[
        Path,
        typer.Option(
            exists=True,
            file_okay=True,
            dir_okay=False,
            writable=False,
            readable=True,
            resolve_path=True,
        ),
    ],
):
    text = config.read_text()
    print(f"Config file contents: {text}")


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

提示

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

from pathlib import Path

import typer


def main(
    config: Path = typer.Option(
        ...,
        exists=True,
        file_okay=True,
        dir_okay=False,
        writable=False,
        readable=True,
        resolve_path=True,
    ),
):
    text = config.read_text()
    print(f"Config file contents: {text}")


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

检查一下

$ python main.py --config config.txt

Usage: main.py [OPTIONS]
Try "main.py --help" for help.

Error: Invalid value for '--config': File 'config.txt' does not exist.

// Now create a quick config
$ echo "some settings" > config.txt

// And try again
$ python main.py --config config.txt

Config file contents: some settings

// And with a directory
$ python main.py --config ./

Usage: main.py [OPTIONS]
Try "main.py --help" for help.

Error: Invalid value for '--config': File './' is a directory.

高级 Path 配置

高级细节

您可能一开始不需要这些配置,您可能想跳过它。

它们用于更高级的用例。

  • allow_dash: 如果设置为 True,则允许使用单个连字符来表示标准流。
  • path_type: 可选的字符串类型,用于表示路径。默认值为 None,这意味着返回值将是字节或 Unicode,具体取决于 Click 处理的输入数据最适合哪种类型。