Python3 Click模块的使用方法详解

码头散步
码头散步
发布时间:2026-10-13| 6人浏览过
原创

本文详细介绍Python3中Click模块的使用方法。Click由Flask团队开发,通过装饰器将函数转换为命令行接口。文章涵盖Command与Group对象的使用、option与argument参数的区别、类型限制、多值处理、交互式提示及打包部署等核心功能,帮助开发者快速构建跨平台命令行工具。

Click是由Flask团队所属的pallets组织开发的优秀开源项目,它封装了大量命令行工具开发方法,使开发者能够专注于功能实现。鉴于近期开发的小工具需要在命令行环境下运行,特此整理一份学习笔记。

按照惯例,首先展示一段“Hello World”程序(假设已安装Click包)。


# hello.py
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
       help='The person to greet.')
def hello(count, name):
  """Simple program that greets NAME for a total of COUNT times."""
  for x in range(count):
    click.echo('Hello %s!' % name)
if __name__ == '__main__':
  hello()

执行 python hello.py --count=3,可以推测控制台的输出结果。此外,Click还自动提供了帮助选项功能:


$ python hello.py --help
Usage: hello.py [OPTIONS]
 Simple program that greets NAME for a total of COUNT times.
Options:
 --count INTEGER Number of greetings.
 --name TEXT   The person to greet.
 --help      Show this message and exit.

函数秒变CLI

从上述“Hello World”演示可见,Click通过装饰器将函数方法转换为命令行接口,该装饰器为 `@click.command()`。


import click
@click.command()
def hello():
  click.echo('Hello World!')

`@click.command()` 装饰器将 hello() 方法转换为 Command 对象,调用时执行实例内的行为。而 --help 参数即为 Command 对象内置的参数。

不同的 Command 实例可以关联到 group 中,group 下绑定的命令即成为其子命令,参考以下代码:


@click.group()
def cli():
  pass
@click.command()
def initdb():
  click.echo('Initialized the database')
@click.command()
def dropdb():
  click.echo('Dropped the database')
cli.add_command(initdb)
cli.add_command(dropdb)

`@click.group()` 装饰器将方法装饰为可拥有多个子命令的 Group 对象。可通过 Group.add_command() 方法将 Command 对象关联到 Group 对象,也可直接使用 `@Group.command()` 装饰方法,系统会自动将方法关联到该 Group 对象下。


@click.group()
def cli():
  pass
@cli.command()
def initdb():
  click.echo('Initialized the database')
@cli.command()
def dropdb():
  click.echo('Dropped the database')

命令行参数不可或缺,Click 支持对 command 方法添加自定义参数,由 option() 和 argument() 装饰器实现。


@click.command()
@click.option('--count', default=1, help='number of greetings')
@click.argument('name')
def hello(count, name):
  for x in range(count):
    click.echo('Hello %s!' % name)

打包跨平台可执行程序

编写好简单的命令行方法后,需将 .py 文件转换为可在控制台运行的程序。最简单的方法是在文件末尾添加如下代码:


if __name__ == '__main__':
  command()

Click 支持使用 setuptools 更好地实现命令行程序打包,将源码文件打包为系统中的可执行程序,且不限平台。通常会在源码根目录下创建 setup.py 脚本,先查看一段简单的打包代码:


from setuptools import setup
setup(
  name='hello',
  version='0.1',
  py_modules=['hello'],
  install_requires=[
    'Click',
  ],
  entry_points='''
    [console_scripts]
    hello=hello:cli
  ''',
)

注意 entry_points 字段,在 console_scripts 下,每一行代表一个控制台脚本,等号左侧为脚本名称,右侧为 Click 命令的导入路径。

详解命令行参数

前文提到的自定义命令行参数两个装饰器:`@click.option()` 和 `@click.argument()`,两者存在细微区别,使用场景也有所不同。

总体而言,argument() 装饰器功能较简单,而 option() 支持以下特性:

  • 自动提示缺失的输入;
  • option 参数可从环境变量中获取,argument 参数则不支持;
  • option 参数在 help 输出中包含完整文档,argument 则没有;

而 argument 参数可接受可变个数的参数值,option 参数仅能接收固定个数的参数值(默认为 1 个)。

Click 可设置不同的参数类型,简单类型包括 click.STRING、click.INT、click.FLOAT、click.BOOL。

命令行参数名由 “-short_name” 和 “–long_name” 声明,若参数名既不以 “-“ 开头,也不以 “–” 开头,则该变量名将成为被装饰方法的内部变量,而非方法参数。

Option 参数

option 最基础的用法是简单值变量,option 接收一个变量值,示例代码如下:


@click.command()
@click.option('--n', default=1)
def dots(n):
  click.echo('.' * n)

若在命令行后跟随参数 --n=2,则输出两个点;若不传参数,默认输出一个点。上述代码中未显式给出参数类型,但解释器会将其视为 INT 型,因为默认值 1 是 int 值。

有时需要传入多个值,可理解为 list,option 仅支持固定长度的参数值,即设置后必须传入,个数由 nargs 确定。


@click.command()
@click.option('--pos', nargs=2, type=float)
def findme(pos):
  click.echo('%s / %s' % pos)
findme --pos 2.0 3.0 输出结果就是 2.0 / 3.0

既然支持传入 list,那么 tuple 呢?Click 同样支持:


@click.command()
@click.option('--item', type=(unicode, int))
def putitem(item):
  click.echo('name=%s id=%d' % item)

这样便传入了一个 tuple 变量,执行 putitem --item peter 1338 得到的输出即为 name=peter id=1338

上述代码未设置 nargs,因为 nargs 会自动取 tuple 的长度值。因此上述代码实际上等同于:


@click.command()
@click.option('--item', nargs=2, type=click.Tuple([unicode, int]))
def putitem(item):
  click.echo('name=%s id=%d' % item)

option 还支持同一参数多次使用,类似 git commit -m aa -m bb 中 -m 参数传入了 2 次。option 通过 multiple 标识位来支持这一特性:


@click.command()
@click.option('--message', '-m', multiple=True)
def commit(message):
  click.echo('\n'.join(message))

有时命令行参数是固定的几个值,此时可使用 Click.choice 类型来限定传参的潜在值:


# choice
@click.command()
@click.option('--hash-type', type=click.Choice(['md5', 'sha1']))
def digest(hash_type):
  click.echo(hash_type)

当上述命令行程序参数 --hash-type 不是 md5 或 sha1,将输出错误提示,并且在 --help 提示中也会显示 choice 选项。

若希望命令行程序在用户错误输入或漏掉输入时友好提示,需使用 Click 的 prompt 功能,查看代码:


# prompt
@click.command()
@click.option('--name', prompt=True)
def hello(name):
  click.echo('Hello %s!' % name)

若在执行 hello 时未提供 –name 参数,控制台将提示用户输入该参数。也可自定义控制台的提示输出,将 prompt 改为自定义内容即可。

对于类似账户密码等参数的输入,需进行隐藏显示。option 的 hide_input 和 confirmation_prompt 标识用于控制密码参数的输入:


# password
@click.command()
@click.option('--password', prompt=True, hide_input=True,
       confirmation_prompt=True)
def encrypt(password):
  click.echo('Encrypting password to %s' % password.encode('rot13'))

Click 将上述操作进一步封装为装饰器 click.password_option(),因此上述代码也可简化为:


# password
@click.command()
@click.password_option()
def encrypt(password):
  click.echo('Encrypting password to %s' % password.encode('rot13'))

部分参数会改变命令行程序的执行流程,例如 node 进入 Node 控制台,而 node --version 输出版本号。Click 提供 eager 标识对参数名进行标记,拦截既定的命令行执行流程,转而调用回调方法,执行后直接退出。以下模拟 click.version_option() 的功能,实现 --version 参数名输出版本号:


# eager
def print_version(ctx, param, value):
  if not value or ctx.resilient_parsing:
    return
  click.echo('Version 1.0')
  ctx.exit()
@click.command()
@click.option('--version', is_flag=True, callback=print_version,
       expose_value=False, is_eager=True)
def hello():
  click.echo('Hello World!')

对于类似删除数据库表这样的危险操作,Click 支持弹出确认提示,当 --yes 标识位置为 True 时,会要求用户再次确认:


# yes parameters
def abort_if_false(ctx, param, value):
  if not value:
    ctx.abort()
@click.command()
@click.option('--yes', is_flag=True, callback=abort_if_false,
       expose_value=False,
       prompt='Are you sure you want to drop the db?')
def dropdb():
  click.echo('Dropped all tables!')

测试运行结果如下:


$ dropdb
Are you sure you want to drop the db? [y/N]: n
Aborted!
$ dropdb --yes
Dropped all tables!

同样,Click 对此进行了封装,click.confirmation_option() 装饰器实现了上述功能:


@click.command()
@click.confirmation_option(prompt='Are you sure you want to drop the db?')
def dropdb():
  click.echo('Dropped all tables!')

前文仅讲解了默认的参数前缀 -- 和 -,Click 允许开发者自定义参数前缀(尽管严重不推荐)。


# other prefix
@click.command()
@click.option('+w/-w')
def chmod(w):
  click.echo('writable=%s' % w)
if __name__ == '__main__':
  chmod()

若希望用 / 作为前缀,且像上文一样采用布尔标识,会产生冲突,因为布尔标识也使用 /。这种情况下,可用 ; 代替布尔标识的 /:


@click.command()
@click.option('/debug;/no-debug')
def log(debug):
  click.echo('debug=%s' % debug)
if __name__ == '__main__':
  log()

既然支持 Choice,不难联想到 Range,先查看代码:


# range
@click.command()
@click.option('--count', type=click.IntRange(0, 20, clamp=True))
@click.option('--digit', type=click.IntRange(0, 10))
def repeat(count, digit):
  click.echo(str(digit) * count)
if __name__ == '__main__':
  repeat()

Argument 参数

Argument 的作用类似 Option,但功能不如 Option 全面。

与 Option 一样,Argument 最基础的应用是传递一个简单变量值:


@click.command()
@click.argument('filename')
def touch(filename):
  click.echo(filename)

命令行后跟的参数值被赋值给参数名 filename。

另一个广泛使用的场景是可变参数,同样由 nargs 确定参数个数,变量值以 tuple 形式传入函数:


@click.command()
@click.argument('src', nargs=-1)
@click.argument('dst', nargs=1)
def copy(src, dst):
  for fn in src:
    click.echo('move %s to folder %s' % (fn, dst))

运行程序:


$ copy foo.txt bar.txt my_folder
move foo.txt to folder my_folder
move bar.txt to folder my_folder

Click 支持通过文件名参数对文件进行操作,click.File() 装饰器即用于处理此类操作,尤其在类 Unix 系统下,它支持以 - 符号作为标准输入/输出。


# File

@click.command()
@click.argument('input', type=click.File('rb'))
@click.argument('output', type=click.File('wb'))
def inout(input, output):
  while True:
    chunk = input.read(1024)
    if not chunk:
      break
    output.write(chunk)

运行程序,先将文本写入文件,再读取:


$ inout - hello.txt
hello
^D
$ inout hello.txt -
hello

若参数值仅作为文件名使用,很简单,将 type 指定为 click.Path():


@click.command()
@click.argument('f', type=click.Path(exists=True))
def touch(f):
  click.echo(click.format_filename(f))
$ touch hello.txt
hello.txt
$ touch missing.txt
Usage: touch [OPTIONS] F
Error: Invalid value for "f": Path "missing.txt" does not exist.

更多关于Python3 Click模块的使用方法请查看下面的相关链接

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。