本文介绍 Rich 这个强大的 Python 终端美化库,展示如何在终端中实现丰富的格式、颜色、表格、进度条,以及渲染 Markdown 和语法高亮代码,让终端输出不再单调。
前言 你是否厌倦了单调的黑底白字终端输出?是否希望在终端中也能有丰富的格式、颜色、表格、进度条 ,甚至能渲染 Markdown 和语法高亮代码?
Rich 就是为此而生的 Python 库——它让你的终端输出不再单调,而是变得丰富多彩、美观易读 。
本文将深入介绍 Rich 这个强大的 Python 终端美化库,展示它如何让你的 CLI 工具和脚本变得专业且引人入胜。
什么是 Rich? 核心理念 Rich 是一个 Python 库,用于在终端中实现富文本和美观的格式化 。它的设计目标是:
开箱即用 :API 简洁,易于上手
功能丰富 :表格、进度条、Markdown、语法高亮等开箱即用
跨平台兼容 :支持 Linux、macOS 和 Windows
Jupyter 友好 :无需额外配置即可在 Jupyter 中使用
项目信息
安装 使用 pip 安装:
安装后,运行以下命令测试 Rich 输出:
你将看到 Rich 的各种功能演示!
快速开始 1. Rich Print Rich 提供了 print() 方法,签名与 Python 内置 print() 完全相同,但支持丰富的格式化:
1 2 3 from rich import print print ("Hello, [bold magenta]World[/bold magenta]!" , ":vampire:" , locals ())
输出 (带颜色和 emoji):
2. Rich REPL 在 Python REPL 中安装 Rich 后,所有数据结构都会被美观地打印和高亮:
1 2 >>> from rich import pretty>>> pretty.install()
现在在 REPL 中输入任何对象,Rich 都会自动美化显示。
3. 使用 Console 对象 对于更精细的控制,使用 Console 对象:
1 2 3 4 from rich.console import Consoleconsole = Console() console.print ("Hello" , "World!" )
添加样式 1 2 3 4 5 6 7 console.print ("Hello" , "World!" , style="bold red" ) console.print ( "Where there is a [bold cyan]Will[/bold cyan] there [u]is[/u] a [i]way[/i]." )
Rich Markup 语法 :1 2 3 4 5 [bold]加粗[/bold] [italic]斜体[/italic] [underline]下划线[/underline] [red]红色[/red] [bold magenta]粗体洋红[/bold magenta]
核心功能 1. 美化日志:log() Console.log() 方法类似于 print(),但显示时间、文件和行号:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from rich.console import Consoleconsole = Console() test_data = [ {"jsonrpc" : "2.0" , "method" : "sum" , "params" : [1 , 2 , 4 ], "id" : "1" }, {"jsonrpc" : "2.0" , "method" : "notify_hello" , "params" : [7 ]}, ] def test_log (): enabled = False context = {"foo" : "bar" } movies = ["Deadpool" , "Rise of Skywalker" ] console.log("Hello from" , console, "!" ) console.log(test_data, log_locals=True ) test_log()
输出 (带时间戳、文件名、行号和本地变量表):1 2 3 4 5 6 7 8 9 10 11 12 13 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ test.py ┃ ┃ test_log ┃ ┃ 12:00:00 ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ ┃ Hello from <Console id=0x... │ ┃ {'jsonrpc': '2.0', 'method': 'sum', ...} │ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ ┃ locals() │ ┃ enabled = False │ ┃ context = {'foo': 'bar'} │ ┃ movies = ['Deadpool', 'Rise of Skywalker']│ └─────────────────────────────────────────────────────────────────────────────────
Logging Handler Rich 提供与 Python logging 模块兼容的 Handler:
1 2 3 4 5 6 7 8 9 10 11 import loggingfrom rich.logging import RichHandlerlogging.basicConfig( level="NOTSET" , format ="%(message)s" , handlers=[RichHandler()] ) logger = logging.getLogger(__name__) logger.info("Hello, Rich!" )
2. 表格渲染 Rich 可以渲染美观的 Unicode 表格:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 from rich.console import Consolefrom rich.table import Tableconsole = Console() table = Table(show_header=True , header_style="bold magenta" ) table.add_column("Date" , style="dim" , width=12 ) table.add_column("Title" ) table.add_column("Production Budget" , justify="right" ) table.add_column("Box Office" , justify="right" ) table.add_row( "Dec 20, 2019" , "Star Wars: The Rise of Skywalker" , "$275,000,000" , "$375,126,118" ) table.add_row( "May 25, 2018" , "[red]Solo[/red]: A Star Wars Story" , "$275,000,000" , "$393,151,347" ) console.print (table)
输出 (带 Unicode 边框和对齐):1 2 3 4 5 6 ╭────────────────────────────────────────────────────────────────────────────╮ │ Date │ Title │ Production Budget │ Box Office │ ├────────────────────────────────────────────────────────────────────────────┤ │ Dec 20, 2019 │ Star Wars: The Rise of Skywalker │ $275,000,000 │ $375,126,118 │ │ May 25, 2018 │ Solo: A Star Wars Story │ $275,000,000 │ $393,151,347 │ ╰────────────────────────────────────────────────────────────────────────────╯
3. 进度条 Rich 可以渲染无闪烁的多进度条:
1 2 3 4 from rich.progress import trackfor step in track(range (100 ), description="Processing..." ): do_step(step)
输出 :1 Processing... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 45/100 45%
多个进度条 1 2 3 4 5 6 7 8 9 10 11 from rich.progress import Progresswith Progress() as progress: task1 = progress.add_task("[red]Downloading..." , total=100 ) task2 = progress.add_task("[green]Processing..." , total=100 ) task3 = progress.add_task("[cyan]Uploading..." , total=100 ) while not progress.finished: progress.update(task1, advance=0.1 ) progress.update(task2, advance=0.2 ) progress.update(task3, advance=0.15 )
显示详细信息 1 2 3 4 5 6 7 8 9 10 from rich.progress import track, BarColumn, TextColumn, TimeRemainingColumnfor step in track( range (100 ), description="Downloading" , console=console, show_speed=True , show_eta=True ): process_step(step)
4. 状态指示器(Spinner) 对于难以计算进度的任务,使用 status() 显示动画:
1 2 3 4 5 6 7 8 9 10 11 from time import sleepfrom rich.console import Consoleconsole = Console() with console.status("[bold green]Working on tasks..." ) as status: tasks = [f"task {n} " for n in range (1 , 11 )] while tasks: task = tasks.pop(0 ) sleep(0.5 ) console.log(f"{task} complete" )
查看所有可用的 spinner :
5. Emoji 支持 在终端输出中使用 emoji(名称在两个冒号之间):
1 2 3 4 from rich.console import Consoleconsole = Console() console.print (":smiley: :vampire: :pile_of_poo: :thumbs_up: :raccoon:" )
输出 :
6. 树形结构渲染 1 2 3 4 5 6 7 8 9 10 11 from rich.tree import Treefrom rich.console import Consoleconsole = Console() tree = Tree("📁 project" ) tree.add("📁 src" ).add("📄 main.py" ) tree.add("📁 tests" ) tree.add("📄 README.md" ) console.print (tree)
输出 :1 2 3 4 5 📁 project ├─ 📁 src │ └─ 📄 main.py ├─ 📁 tests └─ 📄 README.md
7. 多列布局 1 2 3 4 5 6 7 8 import osfrom rich.console import Consolefrom rich.columns import Columnsconsole = Console() directory = os.listdir("." ) console.print (Columns(directory))
8. Markdown 渲染 1 2 3 4 5 6 7 8 from rich.console import Consolefrom rich.markdown import Markdownconsole = Console() with open ("README.md" ) as readme: markdown = Markdown(readme.read()) console.print (markdown)
Rich 会将 Markdown 格式转换为终端友好的输出。
9. 语法高亮 1 2 3 4 5 6 7 8 9 10 11 12 from rich.console import Consolefrom rich.syntax import Syntaxconsole = Console() my_code = ''' def hello_world(): print("Hello, World!") ''' syntax = Syntax(my_code, "python" , theme="monokai" , line_numbers=True ) console.print (syntax)
输出 (带语法高亮和行号):1 2 1 │ def hello_world(): 2 │ print("Hello, World!")
支持的语言 :Python, JavaScript, HTML, CSS, JSON, YAML 等(基于 Pygments)
10. 美化异常(Tracebacks) 设置 Rich 为默认异常处理器:
1 2 3 from rich.traceback import installinstall(show_locals=True )
现在任何未捕获的异常都会被美观地显示,包括:
彩色语法高亮
清晰的堆栈跟踪
局部变量值(show_locals=True)
输出示例 :1 2 3 4 5 6 7 8 9 10 11 12 Traceback (most recent call last): File "test.py", line 12, in <module> do_something() File "test.py", line 8, in do_something result = divide(10, 0) ZeroDivisionError: division by zero ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ locals() │ ┃ x = 10 │ ┃ result = None │ └─────────────────────────────────────────────────────────────────────────────────
11. Inspect 功能 生成任何 Python 对象的详细报告:
1 2 3 4 from rich import inspectmy_list = ["foo" , "bar" ] inspect(my_list, methods=True )
实际应用场景 场景 1:CLI 数据导出工具 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from rich.console import Consolefrom rich.table import Tablefrom rich.progress import trackimport jsonconsole = Console() def export_data (data, filename ): with console.status(f"[bold green]Exporting to {filename} ..." ) as status: table = Table(title="Export Summary" ) table.add_column("Metric" ) table.add_column("Value" , justify="right" ) for key, value in data.items(): table.add_row(key, str (value)) console.print (table) with open (filename, "w" ) as f: json.dump(data, f, indent=2 ) status.update(f"[green]Done! {len (data)} records exported" ) export_data({"users" : 1000 , "posts" : 5000 }, "export.json" )
场景 2:长时间运行的服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import loggingfrom rich.logging import RichHandlerlogging.basicConfig( level="INFO" , format ="%(message)s" , datefmt="[%X]" , handlers=[RichHandler(rich_tracebacks=True , tracebacks_show_locals=True )] ) logger = logging.getLogger(__name__) class Server : def start (self ): logger.info("Server starting..." ) while True : try : self .handle_request() except Exception as e: logger.exception(f"Request failed: {e} " ) def handle_request (self ): logger.debug("Processing request..." ) logger.info("Request completed successfully" ) server = Server() server.start()
场景 3:数据科学可视化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from rich.console import Consolefrom rich.table import Tablefrom rich.columns import Columnsfrom rich.panel import Panelconsole = Console() def show_metrics (metrics ): table = Table(show_header=True ) table.add_column("Metric" , style="cyan" ) table.add_column("Value" , style="green" ) for key, value in metrics.items(): table.add_row(key, f"{value:.2 f} " ) panel = Panel(table, title="[bold]Metrics Dashboard" , border_style="blue" ) console.print (panel) metrics = { "Accuracy" : 0.95 , "Precision" : 0.92 , "Recall" : 0.89 , "F1 Score" : 0.90 } show_metrics(metrics)
场景 4:下载器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import requestsfrom rich.progress import Progress, BarColumn, TextColumn, DownloadColumn, TransferSpeedColumn, TimeRemainingColumnfrom rich.console import Consoleconsole = Console() def download_file (url, filename ): response = requests.get(url, stream=True ) total_size = int (response.headers.get('content-length' , 0 )) with Progress( TextColumn("[bold blue]{task.description}" ), BarColumn(bar_width=None ), DownloadColumn(), TransferSpeedColumn(), TimeRemainingColumn(), ) as progress: task = progress.add_task(f"Downloading {filename} " , total=total_size) with open (filename, 'wb' ) as f: for chunk in response.iter_content(chunk_size=8192 ): f.write(chunk) progress.update(task, advance=len (chunk)) console.print (f"[green]✓[/green] Downloaded {filename} " ) download_file( "https://example.com/large-file.zip" , "large-file.zip" )
高级技巧 1. 自定义 Console 1 2 3 4 5 6 7 8 9 10 11 12 13 from rich.console import Consolefrom rich.theme import Themecustom_theme = Theme({ "info" : "dim cyan" , "warning" : "magenta" , "error" : "bold red" }) console = Console(theme=custom_theme) console.print ("[info]This is an info message" ) console.print ("[warning]This is a warning" ) console.print ("[error]This is an error" )
2. 永久更改样式 1 2 3 4 5 6 7 8 9 10 11 from rich.console import Consoleconsole = Console() with console.capture(): console.print ("This won't be displayed" ) output = console.get() console.print (f"Captured: {output} " )
3. 布局控制 1 2 3 4 5 6 7 8 9 10 11 12 13 from rich.console import Consolefrom rich.layout import Layoutfrom rich.panel import Panelconsole = Console() layout = Layout() layout["header" ].update(Panel("My App" , style="bold blue" )) layout["body" ].update("Content goes here" ) layout["footer" ].update("Status: Ready" ) console.print (layout)
4. 分组和规则 1 2 3 4 5 6 7 8 9 from rich.console import Consolefrom rich.rule import Ruleconsole = Console() console.print (Rule("[bold red]Section 1" , style="red" )) console.print ("Content of section 1" ) console.print (Rule("[bold green]Section 2" , style="green" )) console.print ("Content of section 2" )
兼容性 平台支持
平台
支持状态
备注
Linux
✅ 完全支持
真彩色和 emoji 完全支持
macOS
✅ 完全支持
真彩色和 emoji 完全支持
Windows
✅ 支持
新终端(Windows Terminal)完全支持;经典终端限制 16 色
Jupyter Notebook
✅ 无需配置
开箱即用
Python 版本
最低要求 :Python 3.8+
推荐 :Python 3.10+
最佳实践 1. 性能考虑 1 2 3 4 5 6 7 8 9 for item in items: console = Console() console.print (item) console = Console() for item in items: console.print (item)
2. 日志级别选择 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import loggingfrom rich.logging import RichHandlerif development: logging.basicConfig( level="DEBUG" , handlers=[RichHandler()] ) else : logging.basicConfig( level="WARNING" , handlers=[RichHandler()] )
3. 错误处理 1 2 3 4 5 6 7 8 from rich.traceback import installif development: install(show_locals=True ) else : install(show_locals=False )
4. 颜色使用原则 1 2 3 4 5 6 7 console.print ("[green]Success![/green] Task completed" ) console.print ("[yellow]Warning:[/yellow] Low disk space" ) console.print ("[red]Error:[/red] Failed to connect" ) console.print ("[bold red][underline][italic]ERROR!!![/italic][/underline][/bold]" )
与其他工具对比
特性
Rich
Colorama
Termcolor
表格渲染
✅
❌
❌
进度条
✅
❌
❌
Markdown 渲染
✅
❌
❌
语法高亮
✅
❌
❌
Tree 结构
✅
❌
❌
Traceback 美化
✅
❌
❌
跨平台
✅
✅
⚠️
简单性
简单
简单
简单
常见问题 Q1: Rich 会影响性能吗? 影响很小 。Rich 在大多数情况下对性能的影响可以忽略不计,但有一些优化建议:
重用 Console 对象而不是重复创建
在生产环境中禁用不必要的特性(如 show_locals)
对于大量输出,考虑禁用某些样式
Q2: Rich 可以在 Windows 上使用吗? 可以 。Rich 完全支持 Windows:
新终端(Windows Terminal) :真彩色和 emoji 完全支持
经典终端 :限制 16 种颜色
CMD :部分支持(建议使用 Windows Terminal 或第三方终端)
Q3: Rich 和 Textual 有什么区别? Rich :专注于输出美化 (表格、进度条、语法高亮等)
Textual :Rich 的姊妹项目,专注于构建完整的终端 UI 应用 (TUI),类似 curses 但更现代化。
Q4: 如何在 Jupyter 中使用 Rich? 无需任何配置 !Rich 自动检测 Jupyter 环境,并使用 HTML/JS 渲染而不是 ANSI 代码。
1 2 3 4 from rich import print print ("Hello, [bold]Jupyter![/bold]" )
Q5: Rich 支持哪些颜色主题? Rich 使用 Pygments 进行语法高亮,支持所有 Pygments 主题:
monokai
github-dark
solarized-dark
nord
dracula
等等…
查看所有主题:1 python -c "from pygments.styles import get_all_styles; print([s.name for s in get_all_styles()])"
总结 Rich 是一个让 Python 终端输出变得美观、专业且功能丰富 的强大工具。
核心优势
简单易用 :API 直观,开箱即用
功能强大 :表格、进度条、Markdown、语法高亮等
跨平台 :支持 Linux、macOS、Windows 和 Jupyter
美观输出 :Unicode 支持、真彩色、emoji
生产就绪 :与 logging 模块集成、可配置
适用场景
✅ CLI 工具开发
✅ 长时间运行的服务
✅ 数据科学可视化
✅ 脚本和自动化工具
✅ 调试和日志记录
✅ 下载器和数据处理工具
资源链接
如果你还在使用单调的终端输出,试试 Rich 吧——它会让你的 Python 终端体验焕然一新! 🎨