惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LangChain Blog
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
A
About on SuperTechFans
J
Java Code Geeks
量子位
博客园 - 三生石上(FineUI控件)
博客园 - Franky
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
IT之家
IT之家
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
Engineering at Meta
Engineering at Meta
雷峰网
雷峰网
D
DataBreaches.Net
人人都是产品经理
人人都是产品经理
Martin Fowler
Martin Fowler
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

又耳笔记

用AI挣钱之AI建站:二维码生成器工具 用AI挣钱之AI建站:https://markdowntopdf.top Cloudflare Workers实战番外一:用Static Assets托管网站,告别传统方案 Cloudflare Workers实战(五):不止JavaScript,拥抱Python与Rust Cloudflare Workers实战(四):托管和分发静态文件 Cloudflare Workers实战(三):实现认证、重定向与缓存 Cloudflare Workers实战(二):动态修改后端响应 Cloudflare Workers实战(一):随心所欲操作客户端请求 Cloudflare workers不完全指南 使用n8n创作短篇小说 水果风波:信任的代价 用Python将PDF文件转换成图片 rust网络框架Pingora源码阅读3 rust网络框架Pingora源码阅读2 rust网络框架Pingora源码阅读1 Pingora快速入门教程1之总览 Rust模板引擎askama快速入门引擎 使用Loco快速搭建自己的后台系统 用Rust发一封图文并茂的邮件 Rust小项目: 写一个简单的恶意流量阻断器 Rust小项目: 写一个简单的网页爬虫 Rust命令行库Clap快速入门教程 Rust小项目:用Rust写一个端口扫描器 Rust真全栈开发快速入门 rust声明宏快速入门教程 Rust文本处理快速入门教程 RUST web框架axum快速入门教程6之测试 白嫖免费的Rust在线运行时shuttle RUST web框架axum快速入门教程5之中间件 用Rust来做以太坊开发5之事件日志及签名
python命令行typer 快速入门教程
About 又耳宁 关于技术与股票的一些零碎想法 · 2023-05-15 · via 又耳笔记

typer的作者与著名项目FastAPI是同一个作者,作者擅长在已有库的基础上大幅度的提升用户体验,typer自然也不例外, 因为作者也大力提倡python的类型标注,所以typer的使用在Python 3.6+才能获得最佳体验。

类型标注很棒的一个点在于编程的时候有方法补全即类型验证。

在学习typer之前我们应该先了解一下命令行下的参数类型,typer将命令行参数分为了两类,一类叫做Argument(位置参数), 一类叫做Options(可选参数)。

以下面的命令为例

ls -l -a -h --color=auto /tmp  /var/log

上面的命令可以分为三个部分, ls, -l -a -h, /tmp /var/log, 第一部分是可执行文件名, 第而部分是Options(可选参数), 第三部分是Arguments(位置参数)。

如果你使用linux命令足够多,你会注意到Options(可选参数)不都是上述说明的那样,比如下面的命令

ls -l -a -h --color=auto /tmp  /var/log

可以看到上面的命令多了--color=auto这样的Options。

总的来说在这两类参数中,Options(可选参数)总是以一个或多个-(横线)开头, 而命令行参数一般不以-(横线)开头。

但,事情总有意外, 比如linux的很多命令接受参数-(横线), 表示读取标准输出, 这个参数说实话,还真不好分类,个人倾向于分为Arguments(命令行参数)。

快速入门

推荐安装一个全功能的typer, 这样可以获得最棒的体验。

一个官方的例子

import typer


def main(name: str):
    print(f"Hello {name}")


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

不传参的情况

python simple.py
# 输出如下
Usage: simple.py [OPTIONS] NAME
Try 'simple.py --help' for help.

Error: Missing argument 'NAME'.

提示缺少参数NAME

传参的情况下

python simple.py world
# 输出如下
Hello world

可以看到输出正常了,那么为什么呢?

就像FastAPI一样,作者极大的减少了显式的标注参数及其类型(相对于click而言), 上面简单的例子,我们并不需要像使用 Click 一样通过显示的标注参数类型(比如@click.argument('name')),因为typer按照约定将参数分类了,这样我可以减少很多烦人的标注代码,更多的专注于自己的业务。

默认情况下python的命令行参数会被转化成Arguments(位置参数), 而可选参数会转化成Options(可选参数)。以下面代码为例

import typer


def main(name: str, age: int = 18):
    print(f"Hello {name}, your age is {age}")


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

下面是使用及输出

python simple2.py zhangsan .
# 不设置options,则使用默认参数
Hello zhangsan, your age is 18

python simple2.py zhangsan --age=188
# 手动设置options, 则覆盖默认参数
Hello zhangsan, your age is 188

并且我们也可以看看typer帮我们生成的帮助文档

python simple2.py --help
Usage: simple2.py [OPTIONS] NAME

Arguments:
  NAME  [required]

Options:
  --age INTEGER         [default: 18]
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or
                        customize the installation.

  --help                Show this message and exit.

非常棒,不是吗? 这个命令行的内容几乎和一个正常的脚本相同,唯一的不同是引入了typer并调用了它的typer.run方法,仅仅增加两行代码,就得到了一个看起来像模像样的命令行程序了。

注意: 如果age参数传一个字符串会报错,这是因为我们类型标注了age的类型是int!!!

Arguments(命令行参数)

仅仅通过将python的语法按照约定转换成参数自然是很方便的,不过为了更多的控制,显然需要更复杂的类型标注,所以我们需要显示的设置Arguments的各个值。既然也要显式的标注,那这和Click有啥区别? 个人觉得typer更符合直觉(当然了, 这是比较主观的看法).

下面看看Arguments各方面的常用配置。

设置默认值

def main(name: str = typer.Argument("Wade Wilson")):
    print(f"Hello {name}")

设置提示文字

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

读取环境变量

def main(name: str = typer.Argument("World", envvar="AWESOME_NAME")):
    print(f"Hello Mr. {name}")

Options(可选参数)

Arguments一样, Options也有各种选项。

标记可选参数必须设置

def main(name: str, lastname: Annotated[str, typer.Option()]):
    print(f"Hello {name} {lastname}")

如果参数没有设置,会提示

def main(name: str, lastname: str = typer.Option(..., prompt=True)):
    print(f"Hello {name} {lastname}")

重复确认

def main(
    name: str, email: str = typer.Option(..., prompt=True, confirmation_prompt=True)
):
    print(f"Hello {name}, your email is {email}")

密码字段隐藏

def main(
    name: str,
    password: str = typer.Option(
        ..., prompt=True, confirmation_prompt=True, hide_input=True
    ),
):
    print(f"Hello {name}. Doing something very secure with password.")
    print(f"...just kidding, here it is, very insecure: {password}")

Command(子命令)

除非极其简单的命令,不然一般会有多个子命令,所以支持子命令是一个理所当然的事情,示例代码如下

import typer

app = typer.Typer()


@app.command()
def create(item: str):
    print(f"Creating item: {item}")


@app.command()
def delete(item: str):
    print(f"Deleting item: {item}")


@app.command()
def sell(item: str):
    print(f"Selling item: {item}")


if __name__ == "__main__":
    app()

如果我们查看帮助文档会有以下提示

python cm.py --help
Usage: cm.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or
                        customize the installation.

  --help                Show this message and exit.

Commands:
  create
  delete
  sell

每个子命令的参数也可像上面没有使用@app.command()装饰器一样那样类型标注。

总结

如果你习惯了使用python的类型标注,那么写起typer来还是比较轻松自然的,如果还不习惯python的类型标注就去尝试一下FastAPI这个非常棒的python web框架吧, 在深入使用之后你会爱上python的类型标注的。

更多参数及配置参考官方文档Typer