ZetCode

Python rich

最后修改于 2024 年 1 月 29 日

在本文中,我们使用 Python rich 库在终端中创建富文本和高级格式。

Rich 模块允许我们添加颜色、表情符号、表格、列或进度条。我们可以进行语法高亮、美观打印。它支持 markdown 语法。

Rich 开箱即用地支持 Jupyter notebooks。在 Windows 上,新的 Windows Terminal 支持更高级的格式选项。

$ pip install rich

我们使用 pip 安装该库。

Python rich 简单示例

以下是一个使用 rich 的简单示例。

simple.py
#!/usr/bin/python

from datetime import date
from rich import print
from rich import print as rprint

print("[italic red]an old falcon[/italic red]")
rprint("[italic blue]an old falcon[/italic blue]")

print("{ 'name': 'John Doe', 'occupation': 'gardener' }")
print(date.today())

在示例中,我们显示彩色文本。

from rich import print
from rich import print as rprint

从模块中,我们导入两个函数:printrprint。这两个函数是相同的。如果我们不想隐藏内置的 print 函数,可以使用 rprint。对于更高级的选项,我们可以使用 Console 对象。

print("[italic red]an old falcon[/italic red]")

我们以斜体红色打印一条消息。格式指令放在 [] 字符对之间。

print("{ 'name': 'John Doe', 'occupation': 'gardener' }")
print(date.today())

Rich 会自动高亮 JSON 数据和 ISO8601 格式的 datetime。

Python rich 文本

除了在 print 函数中指定格式选项外,我们还可以使用 Text 对象。它封装了带有颜色和样式的文本。

rich_text.py
#!/usr/bin/python

from rich.console import Console
from rich.text import Text

txt = Text('''Python is a general-purpose, dynamic, object-oriented \
programming language. The design purpose of the Python language \
emphasizes programmer productivity and code readability.''', style='italic')

console = Console()
console.print(txt)

该示例将一条消息打印到终端。文本是斜体。

txt = Text('''Python is a general-purpose, dynamic, object-oriented \
programming language. The design purpose of the Python language \
emphasizes programmer productivity and code readability.''', style='italic')

创建了一个文本对象。我们指定了一个样式选项。

Python rich 分隔线

分隔线是带有可选中心标题的水平线。

rules.py
#!/usr/bin/python

from rich.console import Console

console = Console()

console.rule('Python', style='blue')
console.print('''Python is a general-purpose, dynamic, object-oriented\
programming language. The design purpose of the Python language\
emphasizes programmer productivity and code readability.''')
console.print()

console.rule('F#', style='red')
console.print('''F# is a universal programming language for writing succinct,\
robust and performant code.''')
console.print()

console.rule('Go')
console.print('''Go is an open source programming language that makes it easy to\
build simple, reliable, and efficient software. Go is a statically\
typed, compiled programming language.''')

在程序中,我们创建了三条水平线。

console.rule('Python', style='blue')

我们可以为分隔线指定样式。

Python rich 面板

面板是一个在其内容周围绘制边框的控制台可渲染对象。

simple_panel.py
#!/usr/bin/python

from rich.panel import Panel
from rich.console import Console

pnl1 = Panel("[bold yellow]an old falcon", expand=False, border_style="blue")
pnl2 = Panel.fit("[bold yellow]an old falcon", border_style="blue")

console = Console()
console.print(pnl1)
console.print(pnl2)

程序创建一个带有彩色文本的面板。面板有一个蓝色边框。

pnl1 = Panel("[bold yellow]an old falcon", expand=False, border_style="blue")
pnl2 = Panel.fit("[bold yellow]an old falcon", border_style="blue")

我们创建了两个带文本的面板。默认情况下,面板是展开的。我们可以通过 expand 选项将其关闭,或者使用 fit 方法。

Python rich 填充

使用 Padding,我们可以在内容周围添加间距。

padding.py
#!/usr/bin/python

from rich import print
from rich.padding import Padding
from rich.panel import Panel

p = Padding("Hello", (2, 4), style="on blue", expand=False)
print(p)

pnl = Panel.fit(Padding("old falcon", (8, 4)))
print(pnl)

在程序中,我们在文本周围添加了空格。

p = Padding("Hello", (2, 4), style="on blue", expand=False)
print(p)

第二个参数是填充尺寸:上、右、下和左。我们可以指定所有四个值,或者前两个值。

pnl = Panel.fit(Padding("old falcon", (8, 4)))
print(pnl)

我们将填充的文本放入面板中。

Python rich 列

可渲染对象可以放置在列中以便整齐地定位。

words.txt
cup
snow
falcon
eagle
forest
war
water
atom
lamp
pen 
pencil
book
phone
chart
car 
cloud
print 
dog
nose
horse
stream
sum
nail
boot
atom
wind
storm

我们有一系列单词。

cols.py
#!/usr/bin/python

from rich.console import Console
from rich.columns import Columns
from rich.panel import Panel

console = Console()

with open('words.txt', 'r') as f:
    words = f.readlines()

    console.print(Columns([Panel(line, border_style='blue')
                  for line in words], align='center'))

在程序中,我们从文件中读取单词并将它们放入面板中。面板被放置在列中。Rich 根据终端的当前大小排列列。

console.print(Columns([Panel(line, border_style='blue')
              for line in words], align='center'))

我们可以使用 align 选项在列内对齐可渲染对象。

Python rich 组

可渲染对象可以放入组中。

groups.py
#!/usr/bin/python

from rich import print
from rich.console import group
from rich.panel import Panel

@group()
def get_panels():
    yield Panel.fit("an old falcon", style="on blue")
    yield Panel.fit("a long stormy night", style="on deep_sky_blue4")

print(Panel.fit(get_panels()))

from rich.console import Group

g = Group(
    Panel.fit("an old falcon", style="on blue"),
    Panel.fit("a long stormy night", style="on deep_sky_blue4"),
)

print(Panel.fit(g))

在示例中,我们创建了两个组。我们将两个面板添加到每个组中。

@group()
def get_panels():
    yield Panel.fit("an old falcon", style="on blue")
    yield Panel.fit("a long stormy night", style="on deep_sky_blue4")

print(Panel.fit(get_panels()))

在第一种情况下,我们使用装饰器构建了一个组。

g = Group(
    Panel.fit("an old falcon", style="on blue"),
    Panel.fit("a long stormy night", style="on deep_sky_blue4"),
)

print(Panel.fit(g))

在第二种情况下,我们使用了 Group 对象。

Python rich 表格

更复杂的表格数据可以显示在 Table 中。

table.py
#!/usr/bin/python

from rich import box
from rich.console import Console
from rich.table import Table
from datetime import date

now = f'{date.today()}'
table = Table(title='Users', box=box.MINIMAL, caption=now, caption_justify='left')

table.add_column('Name', style='cyan')
table.add_column('Occupation', style='grey69')
table.add_column('Date of birth', justify='right', style='green')

table.add_row('John Doe', 'gardener', '12/5/1997')
table.add_row('Jane Doe', 'teacher', '5/16/1983')
table.add_row('Robert Smith', 'driver', '4/2/2001')
table.add_row('Maria Smith', 'cook', '9/21/1976')

console = Console()
console.print(table, justify='center')

示例在表格中显示用户。

table = Table(title='Users', box=box.MINIMAL, caption=now, caption_justify='left')

创建了一个 Table 对象。我们提供了标题、页眉框样式和字幕。字幕是左对齐的。

table.add_column('Name', style='cyan')
table.add_column('Occupation', style='grey69')
table.add_column('Date of birth', justify='right', style='green')

我们使用 add_column 添加列到表格。每列数据以不同的颜色显示。第三列也右对齐。

table.add_row('John Doe', 'gardener', '12/5/1997')
table.add_row('Jane Doe', 'teacher', '5/16/1983')
table.add_row('Robert Smith', 'driver', '4/2/2001')
table.add_row('Maria Smith', 'cook', '9/21/1976')

我们使用 add_row 添加了四行。

console = Console()
console.print(table, justify='center')

打印表格。整个表格居中。


在下一个示例中,我们在表格中显示 BTC OHLCV 数据。该示例使用 ccxt 模块从 Binance 交易所获取数据。

btc_ohlcv.py
#!/usr/bin/python

import asyncio
import ccxt.async_support as ccxt

from rich import box
from rich.console import Console
from rich.table import Table
from datetime import datetime


async def tickers():

    binance = ccxt.binance()
    data = await binance.fetch_ohlcv('BTC/USDT', '1d', limit=20)
    await binance.close()

    now = f'{datetime.today()}'
    table = Table(title='Binance - BTC/USDT', box=box.ASCII,
                  caption=now, caption_justify='left')

    table.add_column('Date', justify='center', style='steel_blue')
    table.add_column('Open')
    table.add_column('High')
    table.add_column('Low')
    table.add_column('Close')
    table.add_column('Volume', justify='right', style='cadet_blue')

    for e in data:
        d = datetime.utcfromtimestamp(e[0]/1000.0)
        table.add_row(f'{d:%m/%d/%Y}', f'{e[1]:.2f}', f'{e[2]:.2f}',
                      f'{e[3]:.2f}', f'{e[4]:.2f}', f'{e[5]:.5f}')

    console = Console()
    console.print(table)

asyncio.run(tickers())

显示过去 20 天 BTC 的开盘价、最高价、最低价、收盘价、成交量值。

Python rich markdown

Markdown 是一种用于创建格式化文本的轻量级标记语言。Rich 支持 markdown 语言。

pattern_match.md
# Match expressions

The match expression provides branching control that is based on  
the comparison of an expression with a set of patterns.  

## String constant 

```F#
open System
open System.Globalization

printf "What is the capital of Slovakia?: "

let name = Console.ReadLine() 
let lowered = name.ToLower()
let capital = CultureInfo.CurrentCulture.TextInfo.ToTitleCase lowered

let msg = match capital with
            | "Bratislava" -> "correct answer"
            | _ -> "wrong answer"


printfn $"{msg}"
```

我们有一个简短的 markdown 示例。它包含标题和 F# 源代码列表。

markdown.py
#!/usr/bin/python

from rich.console import Console
from rich.markdown import Markdown

with open('pattern_match.md', 'r') as f:

    data = f.read()

    console = Console()
    md = Markdown(data)
    console.print(md)

该程序从文件中读取 markdown 并将数据传递给 Markdown 对象。然后将 markdown 打印到控制台。

Python rich 语法

Rich 可以为多种语言提供语法高亮。

filter.fsx
open System

type User =
    { FirstName: string
      LastName: string
      Salary: int }

let users = [
    
        { FirstName="Robert"; LastName="Novak"; Salary=1770 };
        { FirstName="John"; LastName="Doe";  Salary=1230 };
        { FirstName="Lucy"; LastName="Novak";  Salary=670 };
        { FirstName="Ben"; LastName="Walter";  Salary=2050 };
        { FirstName="Robin"; LastName="Brown";  Salary=2300 };
        { FirstName="Amy"; LastName="Doe";  Salary=1250 };
        { FirstName="Joe"; LastName="Draker";  Salary=1190 };
        { FirstName="Janet"; LastName="Doe";  Salary=980 };
        { FirstName="Peter"; LastName="Novak";  Salary=990 };
        { FirstName="Albert"; LastName="Novak";  Salary=1930 }
]

let avg = users |> List.averageBy (fun user -> float user.Salary)
let users2 = users |> List.filter (fun user -> user.Salary > int avg)

users2 |> List.iter Console.WriteLine

我们有一个 F# 代码示例。

syntax.py
#!/usr/bin/python

from rich.console import Console
from rich.syntax import Syntax

stx = Syntax.from_path("filter.fsx", theme="nord-darker", line_numbers=True)

console = Console()
console.print(stx)

我们从文件中读取 F# 代码并在输出中提供语法高亮。我们使用 nord-darker 主题并启用行号。它会自动检测使用的语言。

来源

Python rich 文档

在本文中,我们使用 rich 模块在 Python 中创建了富文本和格式。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教学编程方面拥有十多年的经验。

列出所有 Python 教程